29 #ifndef OOMPH_MULTI_DOMAIN_CC
30 #define OOMPH_MULTI_DOMAIN_CC
34 #include <oomph-lib-config.h>
71 template<
class BULK_ELEMENT,
unsigned DIM>
75 Mesh*
const& bulk_mesh_pt,
77 const unsigned& interaction)
79 unsigned n_mesh = boundary_in_bulk_mesh.size();
83 if (boundary_in_bulk_mesh.size() != face_mesh_pt.size())
85 std::ostringstream error_message;
86 error_message <<
"Sizes of vector of boundary ids in bulk mesh ("
87 << boundary_in_bulk_mesh.size()
88 <<
") and vector of pointers\n"
89 <<
"to FaceElements (" << face_mesh_pt.size()
90 <<
" doesn't match.\n";
92 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
102 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
104 bulk_face_mesh_pt[i_mesh] =
new Mesh;
106 ->template build_face_mesh<BULK_ELEMENT, FaceElementAsGeomObject>(
107 boundary_in_bulk_mesh[i_mesh], bulk_face_mesh_pt[i_mesh]);
112 unsigned n_face_element = bulk_face_mesh_pt[i_mesh]->nelement();
113 for (
unsigned e = 0;
e < n_face_element;
e++)
118 bulk_face_mesh_pt[i_mesh]->element_pt(
e));
134 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
140 for (
unsigned i = 0;
i < DIM;
i++)
144 for (
unsigned i = 0;
i < DIM - 1;
i++)
159 std::sort(bulk_face_mesh_pt[i_mesh]->element_pt().begin(),
160 bulk_face_mesh_pt[i_mesh]->element_pt().end(),
171 problem_pt, face_mesh_pt, bulk_mesh_pt, bulk_face_mesh_pt, interaction);
175 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
177 unsigned n_face_element = bulk_face_mesh_pt[i_mesh]->nelement();
183 for (
unsigned e = n_face_element;
e > 0;
e--)
185 delete bulk_face_mesh_pt[i_mesh]->element_pt(
e - 1);
186 bulk_face_mesh_pt[i_mesh]->element_pt(
e - 1) = 0;
189 bulk_face_mesh_pt[i_mesh]->flush_element_and_node_storage();
192 delete bulk_face_mesh_pt[i_mesh];
206 template<
class BULK_ELEMENT,
unsigned DIM>
209 const unsigned& boundary_in_bulk_mesh,
210 Mesh*
const& bulk_mesh_pt,
211 Mesh*
const& face_mesh_pt,
212 const unsigned& interaction)
216 boundary_in_bulk_mesh_vect[0] = boundary_in_bulk_mesh;
218 face_mesh_pt_vect[0] = face_mesh_pt;
221 setup_bulk_elements_adjacent_to_face_mesh<BULK_ELEMENT, DIM>(
223 boundary_in_bulk_mesh_vect,
243 template<
class ELEMENT_0,
class ELEMENT_1>
246 Mesh*
const& first_mesh_pt,
247 Mesh*
const& second_mesh_pt,
248 const unsigned& first_interaction,
249 const unsigned& second_interaction)
256 setup_multi_domain_interaction<ELEMENT_1>(
257 problem_pt, first_mesh_pt, second_mesh_pt, first_interaction);
259 setup_multi_domain_interaction<ELEMENT_0>(
260 problem_pt, second_mesh_pt, first_mesh_pt, second_interaction);
279 template<
class EXT_ELEMENT>
282 Mesh*
const& mesh_pt,
283 Mesh*
const& external_mesh_pt,
284 const unsigned& interaction_index)
295 std::ostringstream error_stream;
296 error_stream <<
"The elements within the two interacting meshes have a\n"
297 <<
"dimension not equal to 1, 2 or 3.\n"
298 <<
"The multi-domain method will not work in this case.\n"
299 <<
"The dimension is: " <<
Dim <<
"\n";
301 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
305 aux_setup_multi_domain_interaction<EXT_ELEMENT, EXT_ELEMENT>(
306 problem_pt, mesh_pt, external_mesh_pt, interaction_index);
335 template<
class EXT_ELEMENT,
class FACE_ELEMENT_GEOM_OBJECT>
338 Mesh*
const& mesh_pt,
339 Mesh*
const& external_mesh_pt,
340 Mesh*
const& external_face_mesh_pt,
341 const unsigned& interaction_index)
352 std::ostringstream error_stream;
353 error_stream <<
"The elements within the two interacting meshes have a\n"
354 <<
"dimension not equal to 1 or 2.\n"
355 <<
"The multi-domain method will not work in this case.\n"
356 <<
"The dimension is: " <<
Dim <<
"\n";
358 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
362 aux_setup_multi_domain_interaction<EXT_ELEMENT, FACE_ELEMENT_GEOM_OBJECT>(
367 external_face_mesh_pt);
399 template<
class EXT_ELEMENT,
class FACE_ELEMENT_GEOM_OBJECT>
403 Mesh*
const& external_mesh_pt,
405 const unsigned& interaction_index)
408 unsigned n_mesh = mesh_pt.size();
411 if (external_face_mesh_pt.size() != n_mesh)
413 std::ostringstream error_stream;
414 error_stream <<
"Sizes of external_face_mesh_pt [ "
415 << external_face_mesh_pt.size() <<
" ] and "
416 <<
"mesh_pt [ " << n_mesh <<
" ] don't match.\n";
418 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
423 if (n_mesh == 0)
return;
435 unsigned old_dim =
Dim;
436 for (
unsigned i = 1;
i < n_mesh;
i++)
443 std::ostringstream error_stream;
444 error_stream <<
"Inconsistency: Mesh " <<
i <<
" has Dim=" <<
Dim
445 <<
"while mesh 0 has Dim=" << old_dim << std::endl;
447 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
454 std::ostringstream error_stream;
455 error_stream <<
"The elements within the two interacting meshes have a\n"
456 <<
"dimension not equal to 1 or 2.\n"
457 <<
"The multi-domain method will not work in this case.\n"
458 <<
"The dimension is: " <<
Dim <<
"\n";
460 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
464 aux_setup_multi_domain_interaction<EXT_ELEMENT, FACE_ELEMENT_GEOM_OBJECT>(
469 external_face_mesh_pt);
484 template<
class EXT_ELEMENT,
class GEOM_OBJECT>
487 Mesh*
const& mesh_pt,
488 Mesh*
const& external_mesh_pt,
489 const unsigned& interaction_index,
490 Mesh*
const& external_face_mesh_pt)
494 mesh_pt_vector[0] = mesh_pt;
496 external_face_mesh_pt_vector[0] = external_face_mesh_pt;
499 aux_setup_multi_domain_interaction<EXT_ELEMENT, GEOM_OBJECT>(
504 external_face_mesh_pt_vector);
523 template<
class EXT_ELEMENT,
class GEOM_OBJECT>
527 Mesh*
const& external_mesh_pt,
528 const unsigned& interaction_index,
532 unsigned n_mesh = mesh_pt.size();
535 if (external_face_mesh_pt.size() != n_mesh)
537 std::ostringstream error_stream;
538 error_stream <<
"Sizes of external_face_mesh_pt [ "
539 << external_face_mesh_pt.size() <<
" ] and "
540 <<
"mesh_pt [ " << n_mesh <<
" ] don't match.\n";
542 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
547 if (n_mesh == 0)
return;
558 if (external_mesh_pt->
nelement() != 0)
560 ext_el_pt_0 = external_mesh_pt->
element_pt(0);
564 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
568 if (mesh_pt[i_mesh]->nelement() != 0)
570 el_pt_0 = mesh_pt[i_mesh]->element_pt(0);
578 "Multi-domain setup does not work with spectral elements.",
579 OOMPH_CURRENT_FUNCTION,
580 OOMPH_EXCEPTION_LOCATION);
588 "Multi-domain setup does not work with hp-refineable elements.",
589 OOMPH_CURRENT_FUNCTION,
590 OOMPH_EXCEPTION_LOCATION);
604 double t_start = 0.0;
606 double t_local = 0.0;
608 double t_locate = 0.0;
609 double t_spiral_start = 0.0;
611 double t_loop_start = 0.0;
612 double t_sendrecv = 0.0;
613 double t_missing = 0.0;
614 double t_send_info = 0.0;
615 double t_create_halo = 0.0;
624 unsigned n_zeta_not_found = 0;
632 unsigned el_dim_lag = 0;
637 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
645 std::ostringstream error_stream;
647 <<
"Sorry I currently can't deal with non-bulk external elements\n"
648 <<
"in multi-domain setup for multiple meshes.\n"
649 <<
"The functionality should be easy to implement now that you\n"
650 <<
"have a test case. If you're not willinig to do this, call\n"
651 <<
"the multi-domain setup mesh-by-mesh instead (though this can\n"
652 <<
"be costly in parallel because of global comms. \n";
654 OOMPH_CURRENT_FUNCTION,
655 OOMPH_EXCEPTION_LOCATION);
664 mesh_geom_obj_pt[i_mesh] =
669 unsigned old_el_dim_lag = el_dim_lag;
672 el_dim_lag = mesh_geom_obj_pt[i_mesh]->nlagrangian();
677 if (el_dim_lag != old_el_dim_lag)
679 std::ostringstream error_stream;
680 error_stream <<
"Lagrangian dimensions of elements don't match \n "
681 <<
"between meshes: " << el_dim_lag <<
" "
682 << old_el_dim_lag <<
"\n";
684 OOMPH_CURRENT_FUNCTION,
685 OOMPH_EXCEPTION_LOCATION);
693 double t_setup_lookups = 0.0;
697 oomph_info <<
"CPU for creation of MeshAsGeomObjects and bin structure: "
698 << t_set - t_start << std::endl;
703 unsigned tot_int = 0;
706 unsigned e_count = 0;
709 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
711 e_count += mesh_pt[i_mesh]->nelement();
719 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
722 unsigned n_element = mesh_pt[i_mesh]->nelement();
723 for (
unsigned e = 0;
e < n_element;
e++)
729 mesh_pt[i_mesh]->element_pt(
e));
745 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
751 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
766 <<
"CPU for setup of lookup schemes for located elements/coords: "
767 <<
t - t_setup_lookups << std::endl;
772 unsigned n_max_level = 0;
775 unsigned max_level_reached = 1;
780 unsigned max_n_sample_points_of_sample_point_containers = 0;
783 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
785 if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
789 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
800 if (nsp > max_n_sample_points_of_sample_point_containers)
802 max_n_sample_points_of_sample_point_containers = nsp;
811 unsigned local_max_n_sample_points_of_sample_point_containers =
812 max_n_sample_points_of_sample_point_containers;
815 MPI_Allreduce(&local_max_n_sample_points_of_sample_point_containers,
816 &max_n_sample_points_of_sample_point_containers,
824 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
829 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
845 #ifdef OOMPH_HAS_CGAL
847 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
852 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
862 if (nsp > max_n_sample_points_of_sample_point_containers)
864 max_n_sample_points_of_sample_point_containers = nsp;
873 unsigned local_max_n_sample_points_of_sample_point_containers =
874 max_n_sample_points_of_sample_point_containers;
877 MPI_Allreduce(&local_max_n_sample_points_of_sample_point_containers,
878 &max_n_sample_points_of_sample_point_containers,
897 unsigned i_level = 0;
898 bool has_not_reached_max_level_of_search =
true;
899 while (has_not_reached_max_level_of_search)
910 mesh_pt, external_mesh_pt, mesh_geom_obj_pt, interaction_index);
915 unsigned count_locates = 0;
917 for (
unsigned e = 0;
e < n_ext_loc;
e++)
920 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
931 percentage_coords_located_locally.push_back(
932 100.0 *
double(count_locates) /
double(tot_int));
937 percentage_coords_located_locally.push_back(100.0);
955 oomph_info <<
"CPU for local location of zeta coordinate [spiral level "
956 << i_level <<
"]: " << t_local - t_spiral_start << std::endl
957 <<
"Number of missing zetas: " << n_zeta_not_found
966 unsigned count_local_zetas = n_zeta_not_found;
967 MPI_Allreduce(&count_local_zetas,
977 if ((n_zeta_not_found != 0) &&
981 double t_sendrecv_min = DBL_MAX;
982 double t_sendrecv_max = -DBL_MAX;
983 double t_sendrecv_tot = 0.0;
985 double t_missing_min = DBL_MAX;
986 double t_missing_max = -DBL_MAX;
987 double t_missing_tot = 0.0;
989 double t_send_info_min = DBL_MAX;
990 double t_send_info_max = -DBL_MAX;
991 double t_send_info_tot = 0.0;
993 double t_create_halo_min = DBL_MAX;
994 double t_create_halo_max = -DBL_MAX;
995 double t_create_halo_tot = 0.0;
1002 unsigned ring_count = 0;
1003 for (
int iproc = 1; iproc < n_proc; iproc++)
1023 std::max(t_sendrecv_max, t_sendrecv - t_loop_start);
1025 std::min(t_sendrecv_min, t_sendrecv - t_loop_start);
1026 t_sendrecv_tot += (t_sendrecv - t_loop_start);
1031 iproc, external_mesh_pt, problem_pt, mesh_geom_obj_pt);
1036 t_missing_max = std::max(t_missing_max, t_missing - t_sendrecv);
1037 t_missing_min = std::min(t_missing_min, t_missing - t_sendrecv);
1038 t_missing_tot += (t_missing - t_sendrecv);
1049 std::max(t_send_info_max, t_send_info - t_missing);
1051 std::min(t_send_info_min, t_send_info - t_missing);
1052 t_send_info_tot += (t_send_info - t_missing);
1056 create_external_halo_elements<EXT_ELEMENT>(
1057 iproc, mesh_pt, external_mesh_pt, problem_pt, interaction_index);
1063 std::max(t_create_halo_max, t_create_halo - t_send_info);
1065 std::min(t_create_halo_min, t_create_halo - t_send_info);
1066 t_create_halo_tot += (t_create_halo - t_send_info);
1078 #ifdef OOMPH_HAS_MPI
1081 unsigned count_local_zetas = n_zeta_not_found;
1082 MPI_Allreduce(&count_local_zetas,
1092 if (n_zeta_not_found == 0)
1097 oomph_info <<
"BREAK N-1: CPU for entrire spiral [spiral level "
1098 << i_level <<
"]: " << t_local - t_spiral_start
1109 oomph_info <<
"Ring-based search continued until iteration "
1110 << ring_count <<
" out of a maximum of "
1112 oomph_info <<
"Total, av, max, min CPU for send/recv of remaining "
1113 "zeta coordinates: "
1114 << t_sendrecv_tot <<
" "
1115 << t_sendrecv_tot / double(ring_count) <<
" "
1116 << t_sendrecv_max <<
" " << t_sendrecv_min <<
"\n";
1117 oomph_info <<
"Total, av, max, min CPU for location of missing zeta "
1119 << t_missing_tot <<
" "
1120 << t_missing_tot / double(ring_count) <<
" "
1121 << t_missing_max <<
" " << t_missing_min <<
"\n";
1122 oomph_info <<
"Total, av, max, min CPU for send/recv of new element "
1124 << t_send_info_tot <<
" "
1125 << t_send_info_tot / double(ring_count) <<
" "
1126 << t_send_info_max <<
" " << t_send_info_min <<
"\n";
1127 oomph_info <<
"Total, av, max, min CPU for local creation of "
1128 "external halo objects: "
1129 << t_create_halo_tot <<
" "
1130 << t_create_halo_tot / double(ring_count) <<
" "
1131 << t_create_halo_max <<
" " << t_create_halo_min <<
"\n";
1141 unsigned count_locates = 0;
1143 for (
unsigned e = 0;
e < n_ext_loc;
e++)
1146 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1158 percentage_coords_located_elsewhere.push_back(
1159 100.0 *
double(count_locates) /
double(tot_int));
1164 percentage_coords_located_locally.push_back(100.0);
1177 #ifdef OOMPH_HAS_MPI
1180 unsigned count_local_zetas = n_zeta_not_found;
1181 MPI_Allreduce(&count_local_zetas,
1190 max_level_reached = i_level + 1;
1194 if (n_zeta_not_found == 0)
1199 oomph_info <<
"BREAK N: CPU for entrire spiral [spiral level "
1200 << i_level <<
"]: " << t_local - t_spiral_start
1209 oomph_info <<
"CPU for entrire spiral [spiral level " << i_level
1210 <<
"]: " << t_local - t_spiral_start << std::endl;
1215 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
1217 if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
1221 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
1231 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
1236 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
1243 #ifdef OOMPH_HAS_CGAL
1244 else if (mesh_geom_obj_pt[i_mesh]->sample_point_container_version() ==
1249 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
1263 if (mesh_geom_obj_pt[0]->sample_point_container_version() ==
1267 mesh_geom_obj_pt[0]->sample_point_container_pt());
1270 ->first_sample_point_to_actually_lookup_during_locate_zeta() <=
1271 max_n_sample_points_of_sample_point_containers)
1273 has_not_reached_max_level_of_search =
true;
1277 has_not_reached_max_level_of_search =
false;
1280 else if (mesh_geom_obj_pt[0]->sample_point_container_version() ==
1285 mesh_geom_obj_pt[0]->sample_point_container_pt());
1289 has_not_reached_max_level_of_search =
true;
1293 has_not_reached_max_level_of_search =
false;
1296 #ifdef OOMPH_HAS_CGAL
1297 else if (mesh_geom_obj_pt[0]->sample_point_container_version() ==
1302 mesh_geom_obj_pt[0]->sample_point_container_pt());
1305 ->first_sample_point_to_actually_lookup_during_locate_zeta() <=
1306 max_n_sample_points_of_sample_point_containers)
1308 has_not_reached_max_level_of_search =
true;
1312 has_not_reached_max_level_of_search =
false;
1321 if (n_zeta_not_found != 0)
1326 std::ostringstream error_stream;
1328 <<
"Multi_domain_functions::locate_zeta_for_local_coordinates()"
1331 #ifdef OOMPH_HAS_MPI
1334 error_stream <<
" on proc: "
1339 <<
"\n\n\nThis is most likely to arise because the two meshes\n"
1340 <<
"that are to be matched don't overlap perfectly or\n"
1341 <<
"because the elements are distorted and too small a \n"
1342 <<
"number of sampling points has been used when setting\n"
1343 <<
"up the bin structure.\n\n"
1344 <<
"You should try to increase the value of \n"
1345 <<
"the number of sample points defined in \n\n"
1347 "SamplePointContainerParameters::Default_nsample_points_generated_"
1349 <<
"\n\n from its current value of "
1350 << SamplePointContainerParameters::
1351 Default_nsample_points_generated_per_element
1354 <<
"NOTE: You can suppress this error and \"accept failure\""
1355 <<
" by setting the public boolean \n\n"
1357 "Multi_domain_functions::Accept_failed_locate_zeta_in_setup_multi_"
1358 "domain_interaction\n\n"
1359 <<
" to true. In this case, the pointers to external elements\n"
1360 <<
" that couldn't be located will remain null\n";
1362 std::ostringstream modifier;
1363 #ifdef OOMPH_HAS_MPI
1371 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
1376 modifier <<
"_mesh" << i_mesh;
1379 std::ofstream outfile;
1382 filename,
"missing_coords_mesh%s.dat", modifier.str().c_str());
1383 outfile.open(filename);
1384 unsigned nel = mesh_pt[i_mesh]->nelement();
1385 for (
unsigned e = 0;
e < nel;
e++)
1387 mesh_pt[i_mesh]->finite_element_pt(
e)->output(outfile);
1393 filename,
"missing_coords_ext_mesh%s.dat", modifier.str().c_str());
1394 outfile.open(filename);
1395 nel = external_mesh_pt->
nelement();
1396 for (
unsigned e = 0;
e < nel;
e++)
1404 mesh_geom_obj_pt[i_mesh]->sample_point_container_pt());
1405 if (bin_array_pt != 0)
1408 filename,
"missing_coords_bin%s.dat", modifier.str().c_str());
1409 outfile.open(filename);
1414 sprintf(filename,
"missing_coords%s.dat", modifier.str().c_str());
1415 outfile.open(filename);
1417 error_stream <<
"Number of unlocated elements " << n << std::endl;
1418 for (
unsigned e = 0;
e < n;
e++)
1423 error_stream <<
"Failure to locate in halo element! "
1424 <<
"Why are we searching there?" << std::endl;
1426 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1430 error_stream <<
"Failure at element/intpt: " <<
e <<
" " << ipt
1436 mesh_pt[i_mesh]->element_pt(
e));
1438 unsigned n_dim_el = el_pt->
dim();
1440 for (
unsigned i = 0;
i < n_dim_el;
i++)
1447 for (
unsigned i = 0;
i < n_dim;
i++)
1449 error_stream << x[
i] <<
" ";
1450 outfile << x[
i] <<
" ";
1452 error_stream << std::endl;
1453 outfile << std::endl;
1461 <<
"Mesh and external mesh documented in missing_coords_mesh*.dat\n"
1462 <<
"and missing_coords_ext_mesh*.dat, respectively. Missing \n"
1463 <<
"coordinates in missing_coords*.dat\n";
1465 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
1471 <<
"NOTE: Haven't found " << n_zeta_not_found
1472 <<
" external elements in \n"
1473 <<
"Multi_domain_functions::aux_setup_multi_domain_interaction(...)\n"
1474 <<
"but this deemed to be acceptable because \n"
1475 <<
"Multi_domain_functions::Accept_failed_locate_zeta_in_setup_multi_"
1476 "domain_interaction\n"
1487 <<
"Total CPU for location and creation of all external elements: "
1488 << t_locate - t_start << std::endl;
1492 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
1494 delete mesh_geom_obj_pt[i_mesh];
1501 #ifdef OOMPH_HAS_MPI
1507 bool comm_was_required =
false;
1508 oomph_info <<
"-------------------------------------------" << std::endl;
1509 oomph_info <<
"- Cumulative percentage of locate success -" << std::endl;
1510 oomph_info <<
"--- Spiral -- Found local -- Found else ---" << std::endl;
1511 for (
unsigned level = 0; level < max_level_reached; level++)
1514 << percentage_coords_located_locally[level] <<
" -- "
1515 << percentage_coords_located_elsewhere[level] <<
" ---"
1519 if (percentage_coords_located_elsewhere[level] >
1520 percentage_coords_located_locally[level])
1522 comm_was_required =
true;
1525 oomph_info <<
"-------------------------------------------" << std::endl;
1536 oomph_info <<
"ASSESSMENT OF NEED FOR PARALLEL SEARCH: \n";
1537 oomph_info <<
"=======================================\n";
1538 unsigned status = 0;
1539 if (comm_was_required)
1541 oomph_info <<
"- Ring-based parallel search did successfully locate "
1543 << my_rank << std::endl;
1548 if (max_level_reached > 1)
1551 <<
"- Ring-based parallel search did NOT locate zetas on proc"
1552 << my_rank << std::endl;
1557 <<
"- No ring-based parallel search was performed on proc"
1558 << my_rank << std::endl;
1564 unsigned overall_status = 0;
1565 MPI_Allreduce(&status,
1573 if (overall_status == 1)
1575 oomph_info <<
"- Ring-based, parallel search did succesfully\n";
1576 oomph_info <<
" locate zetas on at least one other proc, so it\n";
1582 if (max_level_reached > 1)
1585 <<
"- Ring-based, parallel search did NOT locate zetas\n";
1586 oomph_info <<
" on ANY other procs, i.e it was useless.\n";
1588 <<
" --> We should really have done more local search\n";
1590 <<
" by reducing number of bins, or doing more spirals\n";
1591 oomph_info <<
" in one go before initiating parallel search.\n";
1596 oomph_info <<
"- No ring-based, parallel search was performed\n";
1604 oomph_info <<
"------------------------------------------" << std::endl;
1606 <<
" elements, and " << std::endl
1608 <<
" external halo elements, "
1610 <<
" external haloed elements" << std::endl;
1613 oomph_info <<
"------------------------------------------" << std::endl;
1615 <<
" nodes, and " << std::endl
1617 <<
" external halo nodes, "
1619 <<
" external haloed nodes" << std::endl;
1620 oomph_info <<
"------------------------------------------" << std::endl;
1628 for (
int iproc = 0; iproc < n_proc; iproc++)
1630 oomph_info <<
"----------------------------------------" << std::endl;
1631 oomph_info <<
"With process " << iproc <<
" there are "
1633 <<
" root halo elements, and "
1635 <<
" root haloed elements" << std::endl
1638 <<
" external halo elements, and "
1640 <<
" external haloed elements." << std::endl;
1642 oomph_info <<
"----------------------------------------" << std::endl;
1643 oomph_info <<
"With process " << iproc <<
" there are "
1644 << external_mesh_pt->
nhalo_node(iproc) <<
" halo nodes, and "
1645 << external_mesh_pt->
nhaloed_node(iproc) <<
" haloed nodes"
1649 <<
" external halo nodes, and "
1651 <<
" external haloed nodes." << std::endl;
1653 oomph_info <<
"-----------------------------------------" << std::endl
1663 oomph_info <<
"CPU for (one way) aux_setup_multi_domain_interaction: "
1664 << t_end - t_start << std::endl;
1669 #ifdef OOMPH_HAS_MPI
1676 template<
class EXT_ELEMENT>
1680 Mesh*
const& external_mesh_pt,
1682 const unsigned& interaction_index)
1685 int my_rank = comm_pt->my_rank();
1693 unsigned zeta_counter = 0;
1697 unsigned counter_for_located_coord = 0;
1700 unsigned e_count = 0;
1703 unsigned n_mesh = mesh_pt.size();
1704 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
1708 unsigned n_element = mesh_pt[i_mesh]->nelement();
1709 for (
unsigned e = 0;
e < n_element;
e++)
1715 mesh_pt[i_mesh]->element_pt(
e));
1724 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1768 int n_cont_inter_values = -1;
1771 n_cont_inter_values =
1773 ->ncont_interpolated_values();
1777 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1780 <<
" Using macro element node update "
1792 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1794 <<
" Number of macro element "
1812 unsigned el_dim = q_el_pt->
dim();
1813 for (
unsigned i_dim = 0; i_dim < el_dim; i_dim++)
1823 std::ostringstream error_stream;
1824 error_stream <<
"Using MacroElement node update\n"
1825 <<
"in a case with non-QElements\n"
1826 <<
"has not yet been implemented.\n";
1828 OOMPH_CURRENT_FUNCTION,
1829 OOMPH_EXCEPTION_LOCATION);
1834 unsigned n_node = f_el_pt->
nnode();
1835 for (
unsigned j = 0; j < n_node; j++)
1837 Node* new_nod_pt = 0;
1840 add_external_halo_node_to_storage<EXT_ELEMENT>(
1846 n_cont_inter_values,
1852 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1855 <<
" Index of existing external halo element "
1860 unsigned external_halo_el_index =
1866 loc_p, 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++;
1923 template<
class EXT_ELEMENT>
1926 Mesh*
const& external_mesh_pt,
1928 unsigned& node_index,
1930 int& n_cont_inter_values,
1939 n_cont_inter_values,
1943 recursively_add_masters_of_external_halo_node_to_storage<EXT_ELEMENT>(
1949 n_cont_inter_values,
1958 template<
class EXT_ELEMENT>
1962 Mesh*
const& external_mesh_pt,
1964 unsigned& node_index,
1966 int& n_cont_inter_values,
1969 for (
int i_cont = -1; i_cont < n_cont_inter_values; i_cont++)
1971 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1973 <<
" Boolean to indicate that continuously interpolated "
1975 << i_cont <<
" is hanging "
1981 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1983 <<
" Number of master nodes "
1992 for (
unsigned m = 0; m < n_master; m++)
1994 Node* master_nod_pt = 0;
1996 add_external_halo_master_node_helper<EXT_ELEMENT>(master_nod_pt,
2000 n_cont_inter_values,
2004 double master_weight =
2009 recursively_add_masters_of_external_halo_node_to_storage<EXT_ELEMENT>(
2015 n_cont_inter_values,
2026 template<
class EXT_ELEMENT>
2028 Node*& new_master_nod_pt,
2030 Mesh*
const& external_mesh_pt,
2032 int& ncont_inter_values,
2037 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2040 <<
" Boolean to trigger construction of new external halo master node "
2046 construct_new_external_halo_master_node_helper<EXT_ELEMENT>(
2047 new_master_nod_pt, new_nod_pt, loc_p, external_mesh_pt, problem_pt);
2051 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2053 <<
" index of existing external halo master node "
2067 template<
class EXT_ELEMENT>
2069 Node*& new_master_nod_pt,
2072 Mesh*
const& external_mesh_pt,
2077 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2079 <<
" ndim for external halo master node "
2084 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2086 <<
" nposition type for external halo master node "
2090 unsigned n_position_type =
2092 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2094 <<
" nvalue for external halo master node "
2104 unsigned n_lag_type;
2105 if (solid_nod_pt != 0)
2107 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2109 <<
" nlagrdim for external halo master solid node "
2114 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2116 <<
" nlagrtype for external halo master solid node "
2126 unsigned n_prev = 1;
2130 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2132 <<
" Boolean: need timestepper "
2138 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2140 <<
" Index minus one of timestepper "
2158 if (alg_nod_pt != 0)
2161 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2163 <<
" Boolean for algebraic boundary node "
2172 if (time_stepper_pt != 0)
2175 time_stepper_pt, n_dim, n_position_type, n_value);
2184 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2186 <<
" Number of boundaries the algebraic master node is on: "
2192 for (
unsigned i = 0;
i < nb;
i++)
2195 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2197 <<
" Algebraic master node is on boundary "
2208 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2210 <<
"Number of additional values created by face element "
2211 <<
"for master node "
2225 if (bnew_master_nod_pt == 0)
2227 throw OomphLibError(
"Failed to cast new node to boundary node\n",
2228 OOMPH_CURRENT_FUNCTION,
2229 OOMPH_EXCEPTION_LOCATION);
2232 if (bnew_master_nod_pt
2233 ->index_of_first_value_assigned_by_face_element_pt() == 0)
2237 new std::map<unsigned, unsigned>;
2242 std::map<unsigned, unsigned>* map_pt =
2247 for (
unsigned i = 0;
i < n_entry;
i++)
2251 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2254 <<
" Key of map entry for master node"
2261 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2264 <<
" Value of map entry for master node"
2272 (*map_pt)[first] = second;
2279 if (time_stepper_pt != 0)
2282 new AlgebraicNode(time_stepper_pt, n_dim, n_position_type, n_value);
2298 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2300 <<
" algebraic node update id for master node "
2305 unsigned update_id =
2311 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2313 <<
" algebraic node number of ref values for master node "
2318 unsigned n_ref_val =
2322 ref_value.resize(n_ref_val);
2323 for (
unsigned i_ref = 0; i_ref < n_ref_val; i_ref++)
2332 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2334 <<
" algebraic node number of geom objects for master node "
2340 unsigned n_geom_obj =
2345 geom_object_pt.resize(n_geom_obj);
2346 for (
unsigned i_geom = 0; i_geom < n_geom_obj; i_geom++)
2348 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2350 <<
" algebraic node: " << i_geom <<
"-th out of "
2351 << n_geom_obj <<
"-th geom index "
2355 unsigned geom_index =
2369 update_id, alg_mesh_pt, geom_object_pt, ref_value);
2374 else if (macro_nod_pt != 0)
2379 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2381 <<
" Boolean for master algebraic node is boundary node "
2388 if (time_stepper_pt != 0)
2391 time_stepper_pt, n_dim, n_position_type, n_value);
2396 n_dim, n_position_type, n_value);
2401 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2404 <<
" Number of boundaries the macro element master node is on: "
2410 for (
unsigned i = 0;
i < nb;
i++)
2413 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2415 <<
" Macro element master node is on boundary "
2425 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2427 <<
" Number of additional values created by face element "
2428 <<
"for macro element master node "
2442 if (bnew_master_nod_pt == 0)
2444 throw OomphLibError(
"Failed to cast new node to boundary node\n",
2445 OOMPH_CURRENT_FUNCTION,
2446 OOMPH_EXCEPTION_LOCATION);
2449 if (bnew_master_nod_pt
2450 ->index_of_first_value_assigned_by_face_element_pt() == 0)
2454 new std::map<unsigned, unsigned>;
2459 std::map<unsigned, unsigned>* map_pt =
2464 for (
unsigned i = 0;
i < n_entry;
i++)
2468 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2471 <<
" Key of map entry for macro element master node"
2478 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2481 <<
" Value of map entry for macro element master node"
2489 (*map_pt)[first] = second;
2496 if (time_stepper_pt != 0)
2499 time_stepper_pt, n_dim, n_position_type, n_value);
2513 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2515 <<
" Bool: need new external halo element "
2525 new_node_update_el_pt);
2528 new_node_update_f_el_pt =
2532 int n_cont_inter_values;
2535 n_cont_inter_values =
2537 ->ncont_interpolated_values();
2541 n_cont_inter_values = -1;
2543 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2545 <<
" Bool: we have a macro element mesh "
2556 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2558 <<
" Number of macro element "
2562 unsigned macro_el_num =
2573 unsigned el_dim = q_el_pt->
dim();
2574 for (
unsigned i_dim = 0; i_dim < el_dim; i_dim++)
2584 std::ostringstream error_stream;
2585 error_stream <<
"You are using a MacroElement node update\n"
2586 <<
"in a case with non-QElements. This has not\n"
2587 <<
"yet been implemented.\n";
2589 OOMPH_CURRENT_FUNCTION,
2590 OOMPH_EXCEPTION_LOCATION);
2594 unsigned n_node = new_node_update_f_el_pt->
nnode();
2595 for (
unsigned j = 0; j < n_node; j++)
2597 Node* new_nod_pt = 0;
2598 add_external_halo_node_to_storage<EXT_ELEMENT>(
2603 new_node_update_f_el_pt,
2604 n_cont_inter_values,
2610 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2612 <<
" Number of already existing external halo element "
2640 unsigned local_node_index;
2641 unsigned n_node = new_node_update_f_el_pt->
nnode();
2642 for (
unsigned j = 0; j < n_node; j++)
2644 if (macro_master_nod_pt == new_node_update_f_el_pt->
node_pt(j))
2646 local_node_index = j;
2653 local_node_index, s_in_macro_node_update_element);
2656 s_in_macro_node_update_element,
2657 geom_object_vector_pt);
2659 else if (solid_nod_pt != 0)
2664 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2666 <<
" Bool master is a boundary (solid) node "
2673 if (time_stepper_pt != 0)
2685 n_lag_dim, n_lag_type, n_dim, n_position_type, n_value);
2690 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2692 <<
" Number of boundaries the solid master node is on: "
2698 for (
unsigned i = 0;
i < nb;
i++)
2701 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2703 <<
" Solid master node is on boundary "
2713 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2715 <<
" Number of additional values created by face element "
2716 <<
"for solid master node "
2730 if (bnew_master_nod_pt == 0)
2732 throw OomphLibError(
"Failed to cast new node to boundary node\n",
2733 OOMPH_CURRENT_FUNCTION,
2734 OOMPH_EXCEPTION_LOCATION);
2737 if (bnew_master_nod_pt
2738 ->index_of_first_value_assigned_by_face_element_pt() == 0)
2742 new std::map<unsigned, unsigned>;
2747 std::map<unsigned, unsigned>* map_pt =
2752 for (
unsigned i = 0;
i < n_entry;
i++)
2756 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2759 <<
" Key of map entry for solid master node"
2766 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2769 <<
" Value of map entry for solid master node"
2777 (*map_pt)[first] = second;
2784 if (time_stepper_pt != 0)
2786 new_master_nod_pt =
new SolidNode(time_stepper_pt,
2796 n_lag_dim, n_lag_type, n_dim, n_position_type, n_value);
2806 dynamic_cast<SolidNode*
>(new_master_nod_pt);
2807 unsigned n_solid_val =
2809 for (
unsigned i_val = 0; i_val < n_solid_val; i_val++)
2811 for (
unsigned t = 0;
t < n_prev;
t++)
2820 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2822 <<
" Bool node is on boundary "
2832 if (time_stepper_pt != 0)
2835 time_stepper_pt, n_dim, n_position_type, n_value);
2844 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2846 <<
" Number of boundaries the master node is on: "
2852 for (
unsigned i = 0;
i < nb;
i++)
2855 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2857 <<
" Master node is on boundary "
2868 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2870 <<
" Number of additional values created by face element "
2871 <<
"for master node "
2885 if (bnew_master_nod_pt == 0)
2887 throw OomphLibError(
"Failed to cast new node to boundary node\n",
2888 OOMPH_CURRENT_FUNCTION,
2889 OOMPH_EXCEPTION_LOCATION);
2892 if (bnew_master_nod_pt
2893 ->index_of_first_value_assigned_by_face_element_pt() == 0)
2897 new std::map<unsigned, unsigned>;
2902 std::map<unsigned, unsigned>* map_pt =
2907 for (
unsigned i = 0;
i < n_entry;
i++)
2911 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2914 <<
" Key of map entry for master node"
2921 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2924 <<
" Value of map entry for master node"
2932 (*map_pt)[first] = second;
2939 if (time_stepper_pt != 0)
2942 new Node(time_stepper_pt, n_dim, n_position_type, n_value);
2946 new_master_nod_pt =
new Node(n_dim, n_position_type, n_value);
2957 for (
unsigned i_val = 0; i_val < n_value; i_val++)
2959 for (
unsigned t = 0;
t < n_prev;
t++)
2967 unsigned n_nod_dim = new_master_nod_pt->
ndim();
2968 for (
unsigned idim = 0; idim < n_nod_dim; idim++)
2970 for (
unsigned t = 0;
t < n_prev;
t++)
2973 new_master_nod_pt->
x(
t, idim) =
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
unsigned max_bin_dimension() const
Max. bin dimension (number of bins in coordinate directions)
virtual void output_bins(std::ofstream &outfile)=0
Output bins (boundaries and number of sample points in them)
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
unsigned & multiplier_for_max_sample_point_to_actually_lookup_during_locate_zeta()
Every time we've completed a "spiral", visiting a finite number of sample points in a deterministic o...
unsigned & last_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points only actually do the locate_zeta calls when when the counter is ...
unsigned & initial_last_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points only actually do the locate_zeta calls when when the counter exc...
unsigned & first_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points only actually do the locate_zeta calls when when the counter exc...
unsigned total_number_of_sample_points_computed_recursively() const
Compute total number of sample points in sample point container.
///////////////////////////////////////////////////////////////////////////// ///////////////////////...
unsigned n_spiral_chunk() const
Number of spirals to be searched in one go const version.
unsigned & current_max_spiral_level()
Access function to current max. spiral level.
unsigned & current_min_spiral_level()
Access function to current min. spiral level.
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
unsigned total_number_of_sample_points_computed_recursively() const
Compute total number of sample points recursively.
unsigned & initial_last_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points recursively from the top level RefineableBinArray (in determinis...
unsigned & first_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points recursively from the top level RefineableBinArray (in determinis...
unsigned & last_sample_point_to_actually_lookup_during_locate_zeta()
When searching through sample points recursively from the top level RefineableBinArray (in determinis...
unsigned & multiplier_for_max_sample_point_to_actually_lookup_during_locate_zeta()
Every time we've completed a "spiral", visiting a finite number of sample points in a deterministic o...
////////////////////////////////////////////////////////////////////
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 ...
GeomObject * geom_object_list_pt(const unsigned &i)
Access function to the ith GeomObject.
////////////////////////////////////////////////////////////////////
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 ...
A class that contains the information required by Nodes that are located on Mesh boundaries....
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.
A template Class for BoundaryNodes; that is Nodes that MAY live on the boundary of a Mesh....
A class to do comparison of the elements by lexicographic ordering, based on the boundary coordinates...
void set_value(const unsigned &i, const double &value_)
Set the i-th stored data value to specified value. The only reason that we require an explicit set fu...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
MacroElement * macro_element_pt(const unsigned &i)
Access to i-th macro element.
This is a base class for all elements that require external sources (e.g. FSI, multi-domain problems ...
Vector< double > & external_element_local_coord(const unsigned &interaction_index, const unsigned &ipt)
Access function to get source element's local coords for specified interaction index at specified int...
void initialise_external_element_storage()
Initialise storage for pointers to external elements and their local coordinates. This must be called...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
Class that is used to create FaceElement from bulk elements and to provide these FaceElement with a g...
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...
void set_boundary_number_in_bulk_mesh(const unsigned &b)
Set function for the boundary number in bulk mesh.
A general Finite Element class.
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.
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing.
virtual std::string tecplot_zone_string(const unsigned &nplot) const
Return string for tecplot zone header (when plotting nplot points in each "coordinate direction")
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...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
unsigned nnode() const
Return the number of nodes.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
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 unsigned nplot_points(const unsigned &nplot) const
Return total number of plot points (when plotting nplot points in each "coordinate direction")
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"...
A Generalised Element class.
bool is_halo() const
Is this element a halo?
Class that contains data for hanging nodes.
void set_master_node_pt(const unsigned &i, Node *const &master_node_pt, const double &weight)
Set the pointer to the i-th master node and its weight.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
MacroElementNodeUpdateMeshes contain MacroElementNodeUpdateNodes which have their own node update fun...
Vector< GeomObject * > geom_object_vector_pt()
Access function to the vector of GeomObject.
Domain *& macro_domain_pt()
Broken assignment operator.
////////////////////////////////////////////////////////////////////
FiniteElement *& node_update_element_pt()
Pointer to finite element that performs the update by referring to its macro-element representation (...
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 add_boundary_node(const unsigned &b, Node *const &node_pt)
Add a (pointer to) a node to the b-th boundary.
unsigned nexternal_haloed_element()
Total number of external haloed elements in this Mesh.
unsigned nexternal_halo_node()
Total number of external halo nodes in this Mesh.
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.
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...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
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...
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
unsigned long nnode() const
Return number of nodes in the mesh.
unsigned nroot_haloed_element()
Total number of root haloed elements in this Mesh.
void delete_all_external_storage()
Wipe the storage for all externally-based elements.
unsigned nhalo_node()
Total number of halo nodes in this Mesh.
void 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...
unsigned nhaloed_node()
Total number of haloed nodes in this Mesh.
unsigned nexternal_haloed_node()
Total number of external haloed nodes in this Mesh.
unsigned long nelement() const
Return number of elements in the mesh.
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
unsigned nroot_halo_element()
Total number of root halo elements in this Mesh.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
void set_hanging_pt(HangInfo *const &hang_pt, const int &i)
Set the hanging data for the i-th value. (hang_pt=0 to make non-hanging)
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
An OomphLibError object which should be thrown when an run-time error is encountered....
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
////////////////////////////////////////////////////////////////// //////////////////////////////////...
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
bool problem_has_been_distributed()
Access to Problem_has_been_distributed flag.
TimeStepper *& time_stepper_pt()
Access function for the pointer to the first (presumably only) timestepper.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
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...
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...
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
////////////////////////////////////////////////////////////////////// //////////////////////////////...
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
bool Doc_full_stats
Boolean to indicate whether to output further info during setup_multi_domain_interaction() routines.
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.
bool Doc_stats
Boolean to indicate whether to output basic info during setup_multi_domain_interaction() routines.
bool Doc_timings
Boolean to indicate whether to doc timings or not.
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...
Vector< double > Flat_packed_located_coordinates
Vector of flat-packed local coordinates for zeta tuples that have been located.
void send_and_receive_located_info(int &iproc, Mesh *const &external_mesh_pt, Problem *problem_pt)
Send location information from current process; Received location information from (current process +...
unsigned Counter_for_flat_packed_unsigneds
Counter used when processing vector of flat-packed unsigneds – this is really "private" data,...
Vector< Vector< unsigned > > External_element_located
Lookup scheme for whether a local element's integration point has had an external element assigned to...
unsigned Dim
Dimension of zeta tuples (set by get_dim_helper) – needed because we store the scalar coordinates in ...
Vector< double > Flat_packed_doubles
Vector of flat-packed doubles to be communicated with other processors.
void send_and_receive_missing_zetas(Problem *problem_pt)
Send the zeta coordinates from the current process to the next process; receive from the previous pro...
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...
void clean_up()
Helper function that clears all the information used during the external storage creation.
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....
Vector< unsigned > Flat_packed_unsigneds
Vector of flat-packed unsigneds to be communicated with other processors – this is really "private" d...
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...
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 ...
std::ofstream Doc_boundary_coordinate_file
Output file to document the boundary coordinate along the mesh boundary of the bulk mesh during call ...
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...
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...
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)
locate zeta for current set of "local" coordinates vector-based version
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...
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...
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.
bool Use_bulk_element_as_external
Boolean to indicate when to use the bulk element as the external element. Defaults to false,...
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 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.
Vector< unsigned > Located_element_status
Vector to indicate (to another processor) whether a located element (that will have to represented as...
unsigned Counter_for_flat_packed_doubles
Counter used when processing vector of flat-packed doubles – this is really "private" data,...
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.
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....
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
@ UseCGALSamplePointContainer
@ UseNonRefineableBinArray
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...