42 namespace Multi_domain_functions
120 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
189 int send_to_proc = my_rank + 1;
190 int recv_from_proc = my_rank - 1;
191 if (send_to_proc == n_proc)
195 if (recv_from_proc < 0)
197 recv_from_proc = n_proc - 1;
203 MPI_Isend(&n_missing_local_zetas,
214 MPI_Recv(&count_zetas,
222 MPI_Wait(&request, MPI_STATUS_IGNORE);
226 if (n_missing_local_zetas != 0)
229 n_missing_local_zetas,
239 if (count_zetas != 0)
249 MPI_Wait(&request, MPI_STATUS_IGNORE);
265 Mesh*
const& external_mesh_pt,
274 int n_proc = comm_pt->nproc();
275 int my_rank = comm_pt->my_rank();
281 Vector<int> received_proc_id_plus_one_of_external_element;
285 int orig_send_proc = my_rank - iproc;
288 orig_send_proc = n_proc + orig_send_proc;
290 int orig_recv_proc = my_rank + iproc;
291 if ((my_rank + iproc) >= n_proc)
293 orig_recv_proc = orig_recv_proc - n_proc;
299 MPI_Isend(&send_count_double_values,
306 int receive_count_double_values = 0;
307 MPI_Recv(&receive_count_double_values,
314 MPI_Wait(&request, MPI_STATUS_IGNORE);
316 if (send_count_double_values != 0)
319 send_count_double_values,
326 if (receive_count_double_values != 0)
328 received_double_values.resize(receive_count_double_values);
329 MPI_Recv(&received_double_values[0],
330 receive_count_double_values,
337 if (send_count_double_values != 0)
339 MPI_Wait(&request, MPI_STATUS_IGNORE);
345 MPI_Isend(&send_count_unsigned_values,
353 int receive_count_unsigned_values = 0;
354 MPI_Recv(&receive_count_unsigned_values,
362 MPI_Wait(&request, MPI_STATUS_IGNORE);
364 if (send_count_unsigned_values != 0)
367 send_count_unsigned_values,
373 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
374 for (
unsigned i = 0;
i < send_count_unsigned_values;
i++)
376 oomph_info <<
"Sent:" <<
i <<
" to orig_proc:" << orig_send_proc
382 if (receive_count_unsigned_values != 0)
384 received_unsigned_values.resize(receive_count_unsigned_values);
385 MPI_Recv(&received_unsigned_values[0],
386 receive_count_unsigned_values,
394 if (send_count_unsigned_values != 0)
396 MPI_Wait(&request, MPI_STATUS_IGNORE);
402 MPI_Isend(&send_count,
409 int receive_count = 0;
410 MPI_Recv(&receive_count,
417 MPI_Wait(&request, MPI_STATUS_IGNORE);
430 if (receive_count != 0)
432 received_located_element_status.resize(receive_count);
433 MPI_Recv(&received_located_element_status[0],
443 MPI_Wait(&request, MPI_STATUS_IGNORE);
458 if (receive_count != 0)
460 received_proc_id_plus_one_of_external_element.resize(receive_count);
461 MPI_Recv(&received_proc_id_plus_one_of_external_element[0],
471 MPI_Wait(&request, MPI_STATUS_IGNORE);
477 unsigned send_count_located_coord =
479 MPI_Isend(&send_count_located_coord,
486 unsigned receive_count_located_coord = 0;
487 MPI_Recv(&receive_count_located_coord,
494 MPI_Wait(&request, MPI_STATUS_IGNORE);
496 if (send_count_located_coord != 0)
499 send_count_located_coord,
506 if (receive_count_located_coord != 0)
508 received_located_coord.resize(receive_count_located_coord);
509 MPI_Recv(&received_located_coord[0],
510 receive_count_located_coord,
517 if (send_count_located_coord != 0)
519 MPI_Wait(&request, MPI_STATUS_IGNORE);
529 for (
int ii = 0; ii < receive_count_double_values; ii++)
534 for (
int ii = 0; ii < receive_count_unsigned_values; ii++)
540 for (
int ii = 0; ii < receive_count; ii++)
543 received_proc_id_plus_one_of_external_element[ii];
547 for (
int ii = 0; ii < int(receive_count_located_coord); ii++)
560 Mesh*
const& external_mesh_pt,
561 int& n_cont_inter_values)
565 iproc, nod_pt, problem_pt, external_mesh_pt, n_cont_inter_values);
569 iproc, nod_pt, problem_pt, external_mesh_pt, n_cont_inter_values);
581 Mesh*
const& external_mesh_pt,
582 int& n_cont_inter_values)
585 for (
int i_cont = -1; i_cont < n_cont_inter_values; i_cont++)
592 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
599 unsigned n_master = hang_pt->
nmaster();
603 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
606 for (
unsigned m = 0; m < n_master; m++)
615 n_cont_inter_values);
626 n_cont_inter_values);
633 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
646 Mesh*
const& external_mesh_pt,
647 int& n_cont_inter_values)
650 unsigned n_ext_haloed_nod =
652 unsigned external_haloed_node_index =
656 if (external_haloed_node_index == n_ext_haloed_nod)
660 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
661 std::stringstream junk;
662 junk <<
"Node needs to be constructed [size="
672 iproc, nod_pt, problem_pt, external_mesh_pt, n_cont_inter_values);
677 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
678 std::stringstream junk;
689 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
702 Mesh*
const& external_mesh_pt,
703 int& n_cont_inter_values)
706 unsigned n_ext_haloed_nod =
708 unsigned external_haloed_node_index;
709 external_haloed_node_index =
713 if (external_haloed_node_index == n_ext_haloed_nod)
718 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
720 "Node needs to be constructed[2]");
730 n_cont_inter_values);
735 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
742 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
757 Mesh*
const& external_mesh_pt,
758 int& n_cont_inter_values)
763 unsigned n_val = nod_pt->
nvalue();
765 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
769 unsigned n_dim = nod_pt->
ndim();
773 bool found_timestepper =
false;
774 unsigned time_stepper_index;
776 for (
unsigned i = 0;
i < n_time_steppers;
i++)
781 found_timestepper =
true;
782 time_stepper_index =
i;
787 if (found_timestepper)
790 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
794 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
801 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
808 if (time_stepper_pt != 0)
818 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
824 unsigned n_bnd = external_mesh_pt->
nboundary();
825 for (
unsigned i_bnd = 0; i_bnd < n_bnd; i_bnd++)
830 boundaries.push_back(i_bnd);
833 unsigned nb = boundaries.size();
835 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
836 std::stringstream junk;
837 junk <<
"Node is on " << nb <<
" boundaries";
840 for (
unsigned i = 0;
i < nb;
i++)
843 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
844 std::stringstream junk;
845 junk <<
"Node is on boundary " << boundaries[
i] <<
" of " << n_bnd;
856 throw OomphLibError(
"Failed to cast new node to boundary node\n",
857 OOMPH_CURRENT_FUNCTION,
858 OOMPH_EXCEPTION_LOCATION);
861 std::map<unsigned, unsigned>* map_pt =
868 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
869 std::stringstream junk;
871 "No additional values were created by face element");
879 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
880 std::stringstream junk;
881 junk <<
"Map size " << map_pt->size() << n_bnd;
885 for (std::map<unsigned, unsigned>::iterator p = map_pt->begin();
890 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
891 std::stringstream junk;
895 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
905 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
923 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
928 unsigned n_ref_val = alg_nod_pt->
nref_value();
930 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
933 for (
unsigned i_ref_val = 0; i_ref_val < n_ref_val; i_ref_val++)
941 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
944 for (
unsigned i_geom = 0; i_geom < n_geom_obj; i_geom++)
952 unsigned found_geom_object = 0;
953 for (
unsigned i_list = 0; i_list < n_geom_list; i_list++)
957 found_geom_object = i_list;
961 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
972 if (solid_nod_pt != 0)
975 for (
unsigned i_val = 0; i_val < n_solid_val; i_val++)
977 for (
unsigned t = 0;
t < n_prev;
t++)
986 for (
unsigned i_val = 0; i_val < n_val; i_val++)
988 for (
unsigned t = 0;
t < n_prev;
t++)
995 for (
unsigned idim = 0; idim < n_dim; idim++)
997 for (
unsigned t = 0;
t < n_prev;
t++)
1012 Node* master_nod_pt,
1014 Mesh*
const& external_mesh_pt,
1015 int& n_cont_inter_values)
1019 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1023 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1027 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1033 if (solid_nod_pt != 0)
1036 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1040 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1045 unsigned n_dim = master_nod_pt->
ndim();
1049 bool found_timestepper =
false;
1050 unsigned time_stepper_index;
1052 for (
unsigned i = 0;
i < n_time_steppers;
i++)
1058 found_timestepper =
true;
1059 time_stepper_index =
i;
1064 if (found_timestepper)
1067 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1071 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1078 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1080 "Master node Not found timestepper");
1085 unsigned n_prev = 1;
1086 if (time_stepper_pt != 0)
1096 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1101 unsigned n_bnd = external_mesh_pt->
nboundary();
1102 for (
unsigned i_bnd = 0; i_bnd < n_bnd; i_bnd++)
1107 boundaries.push_back(i_bnd);
1110 unsigned nb = boundaries.size();
1112 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1113 std::stringstream junk;
1114 junk <<
"Master node is on " << nb <<
" boundaries";
1117 for (
unsigned i = 0;
i < nb;
i++)
1120 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1121 std::stringstream junk;
1122 junk <<
"Master noode is on boundary " << boundaries[
i] <<
" of "
1135 throw OomphLibError(
"Failed to cast new node to boundary node\n",
1136 OOMPH_CURRENT_FUNCTION,
1137 OOMPH_EXCEPTION_LOCATION);
1140 std::map<unsigned, unsigned>* map_pt =
1147 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1148 std::stringstream junk;
1150 "No additional values were created by face element for this master "
1159 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1160 std::stringstream junk;
1161 junk <<
"Map size for master node " << map_pt->size() << n_bnd;
1165 for (std::map<unsigned, unsigned>::iterator p = map_pt->begin();
1170 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1171 std::stringstream junk;
1173 "Key of map entry for master node");
1176 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1178 "Value of map entry for master node");
1187 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1189 "Master node is not on any boundary");
1197 if (alg_nod_pt != 0)
1206 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1211 unsigned n_ref_val = alg_nod_pt->
nref_value();
1213 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1216 for (
unsigned i_ref_val = 0; i_ref_val < n_ref_val; i_ref_val++)
1224 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1226 "Master Alg Node n geom objects");
1228 for (
unsigned i_geom = 0; i_geom < n_geom_obj; i_geom++)
1234 unsigned found_geom_object = 0;
1235 for (
unsigned i_list = 0; i_list < n_geom_list; i_list++)
1239 found_geom_object = i_list;
1243 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1245 "Master node Found geom object");
1253 if (macro_nod_pt != 0)
1260 unsigned n_ext_haloed_el =
1262 unsigned external_haloed_el_index;
1263 external_haloed_el_index =
1265 iproc, macro_node_update_el_pt);
1268 if (external_haloed_el_index == n_ext_haloed_el)
1271 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1273 "Master Node needs to be constructed");
1282 if (macro_mesh_pt != 0)
1285 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1287 "Mesh is macro element mesh");
1294 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1306 unsigned el_dim = q_el_pt->
dim();
1307 for (
unsigned i_dim = 0; i_dim < el_dim; i_dim++)
1315 std::ostringstream error_stream;
1316 error_stream <<
"You are using a MacroElement node update\n"
1317 <<
"in a case with non-QElements. This has not\n"
1318 <<
"yet been implemented.\n";
1320 OOMPH_CURRENT_FUNCTION,
1321 OOMPH_EXCEPTION_LOCATION);
1329 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1331 "Mesh is not a macro element mesh");
1337 unsigned n_node = macro_node_update_finite_el_pt->
nnode();
1338 for (
unsigned j = 0; j < n_node; j++)
1340 Node* new_nod_pt = macro_node_update_finite_el_pt->
node_pt(j);
1345 n_cont_inter_values);
1351 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1353 "External haloed element already exists");
1356 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1358 "Index of existing external haloed element");
1365 if (solid_nod_pt != 0)
1368 for (
unsigned i_val = 0; i_val < n_val; i_val++)
1370 for (
unsigned t = 0;
t < n_prev;
t++)
1381 unsigned n_val = master_nod_pt->
nvalue();
1382 for (
unsigned i_val = 0; i_val < n_val; i_val++)
1384 for (
unsigned t = 0;
t < n_prev;
t++)
1391 for (
unsigned idim = 0; idim < n_dim; idim++)
1393 for (
unsigned t = 0;
t < n_prev;
t++)
1405 Mesh*
const& external_mesh_pt,
1407 unsigned& node_index,
1409 int& n_cont_inter_values,
1414 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1416 <<
" Bool: New node needs to be constructed "
1432 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1434 <<
" Index of existing external halo node "
1443 new_el_pt->
node_pt(node_index) = new_nod_pt;
1455 unsigned& node_index,
1457 Mesh*
const& external_mesh_pt,
1463 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1465 <<
" Number of values of external halo node "
1475 unsigned n_prev = 1;
1479 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1481 <<
" Timestepper req'd for node "
1487 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1489 <<
" Index of timestepper "
1503 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1505 <<
" Is node on boundary? "
1512 if (time_stepper_pt != 0)
1523 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1525 <<
" Number of boundaries the node is on: "
1531 for (
unsigned i = 0;
i < nb;
i++)
1534 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1536 <<
" Node is on boundary "
1546 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1548 <<
" Number of additional values created by face element "
1562 if (bnew_nod_pt == 0)
1564 throw OomphLibError(
"Failed to cast new node to boundary node\n",
1565 OOMPH_CURRENT_FUNCTION,
1566 OOMPH_EXCEPTION_LOCATION);
1573 new std::map<unsigned, unsigned>;
1578 std::map<unsigned, unsigned>* map_pt =
1582 for (
unsigned i = 0;
i < n_entry;
i++)
1586 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1589 <<
" Key of map entry"
1596 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1599 <<
" Value of map entry"
1607 (*map_pt)[first] = second;
1614 if (time_stepper_pt != 0)
1616 new_nod_pt = new_el_pt->
construct_node(node_index, time_stepper_pt);
1632 if (new_alg_nod_pt != 0)
1642 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1644 <<
" Alg node update id "
1649 unsigned update_id =
1656 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1658 <<
" Alg node # of ref values "
1662 unsigned n_ref_val =
1667 ref_value.resize(n_ref_val);
1668 for (
unsigned i_ref = 0; i_ref < n_ref_val; i_ref++)
1681 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1683 <<
" Alg node # of geom objects "
1687 unsigned n_geom_obj =
1692 geom_object_pt.resize(n_geom_obj);
1693 for (
unsigned i_geom = 0; i_geom < n_geom_obj; i_geom++)
1695 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1697 <<
" Alg node: geom object index "
1701 unsigned geom_index =
1715 update_id, alg_mesh_pt, geom_object_pt, ref_value);
1725 if (macro_nod_pt != 0)
1740 s_in_macro_node_update_element);
1744 new_el_pt, s_in_macro_node_update_element, geom_object_vector_pt);
1749 if (solid_nod_pt != 0)
1752 for (
unsigned i_val = 0; i_val < n_solid_val; i_val++)
1754 for (
unsigned t = 0;
t < n_prev;
t++)
1763 unsigned n_new_val = new_nod_pt->
nvalue();
1764 if (n_val > n_new_val)
1766 new_nod_pt->
resize(n_val);
1771 for (
unsigned i_val = 0; i_val < n_val; i_val++)
1773 for (
unsigned t = 0;
t < n_prev;
t++)
1781 unsigned n_dim = new_nod_pt->
ndim();
1782 for (
unsigned idim = 0; idim < n_dim; idim++)
1784 for (
unsigned t = 0;
t < n_prev;
t++)
1787 new_nod_pt->
x(
t, idim) =
1799 Mesh*
const& external_mesh_pt,
1804 unsigned n_mesh = mesh_geom_obj_pt.size();
1808 int n_proc = comm_pt->nproc();
1809 int my_rank = comm_pt->my_rank();
1813 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1843 unsigned i_mesh = 0;
1847 for (
unsigned i = 0;
i < n_zeta;
i++)
1853 for (
unsigned ii = 0; ii <
Dim; ii++)
1860 bool reached_end_of_mesh =
false;
1861 unsigned dbl_max_count = 0;
1862 for (
unsigned ii = 0; ii <
Dim; ii++)
1864 if (x_global[ii] == DBL_MAX)
1867 reached_end_of_mesh =
true;
1872 if (reached_end_of_mesh)
1876 if (dbl_max_count !=
Dim)
1878 std::ostringstream error_stream;
1879 error_stream <<
"Appear to have reached end of mesh " << i_mesh
1880 <<
" but only " << dbl_max_count <<
" out of " <<
Dim
1881 <<
" zeta coordinates have been set to DBX_MAX\n";
1883 OOMPH_CURRENT_FUNCTION,
1884 OOMPH_EXCEPTION_LOCATION);
1888 for (
unsigned ii = 0; ii <
Dim; ii++)
1897 if (i_mesh == n_mesh)
1906 if (!reached_end_of_mesh)
1908 mesh_geom_obj_pt[i_mesh]->locate_zeta(x_global, sub_geom_obj_pt, ss);
1911 if (sub_geom_obj_pt != 0)
1917 source_el_pt =
dynamic_cast<FiniteElement*
>(sub_geom_obj_pt);
1934 int halo_copy_proc = my_rank - iproc;
1938 if (my_rank < iproc)
1940 halo_copy_proc = n_proc + halo_copy_proc;
1951 unsigned n_extern_haloed =
1953 unsigned external_haloed_el_index =
1959 if (external_haloed_el_index == n_extern_haloed)
1966 int n_cont_inter_values = -1;
1969 n_cont_inter_values =
1971 ->ncont_interpolated_values();
1982 if (macro_mesh_pt != 0)
1985 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
1987 "Mesh is macro element mesh[2]");
1999 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2001 "Number of macro element[2]");
2013 unsigned el_dim = q_el_pt->
dim();
2014 for (
unsigned i_dim = 0; i_dim < el_dim; i_dim++)
2022 std::ostringstream error_stream;
2024 <<
"You are using a MacroElement node update\n"
2025 <<
"in a case with non-QElements. This has not\n"
2026 <<
"yet been implemented.\n";
2028 OOMPH_CURRENT_FUNCTION,
2029 OOMPH_EXCEPTION_LOCATION);
2035 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2037 "Mesh is not a macro element mesh [2]");
2047 if (source_finite_el_pt == 0)
2050 "Unable to cast source function to finite element\n",
2051 "Multi_domain_functions::locate_zeta_for_missing_"
2053 OOMPH_EXCEPTION_LOCATION);
2059 unsigned n_node = source_finite_el_pt->
nnode();
2060 for (
unsigned j = 0; j < n_node; j++)
2071 n_cont_inter_values);
2080 #ifdef ANNOTATE_MULTI_DOMAIN_COMMUNICATION
2082 "Index of existing external haloed element[2]");
2090 for (
unsigned ii = 0; ii <
Dim; ii++)
2101 unsigned bulk_el_dim =
2105 for (
unsigned ii = 0; ii < bulk_el_dim; ii++)
2114 for (
unsigned ii = 0; ii <
Dim; ii++)
2129 for (
unsigned ii = 0; ii <
Dim; ii++)
2155 Mesh*
const& external_mesh_pt,
2157 const unsigned& interaction_index)
2163 unsigned n_mesh = mesh_pt.size();
2166 if (mesh_geom_obj_pt.size() != n_mesh)
2168 std::ostringstream error_stream;
2169 error_stream <<
"Sizes of mesh_geom_obj_pt [ "
2170 << mesh_geom_obj_pt.size() <<
" ] and "
2171 <<
"mesh_pt [ " << n_mesh <<
" ] don't match.\n";
2173 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2178 unsigned e_count = 0;
2181 for (
unsigned i_mesh = 0; i_mesh < n_mesh; i_mesh++)
2184 unsigned n_element = mesh_pt[i_mesh]->nelement();
2187 for (
unsigned e = 0;
e < n_element;
e++)
2191 mesh_pt[i_mesh]->element_pt(
e));
2192 #ifdef OOMPH_HAS_MPI
2200 unsigned el_dim = el_pt->
dim();
2206 std::ostringstream error_stream;
2207 error_stream <<
"Dimension of element " << el_dim
2208 <<
" is not consitent with dimension assumed \n"
2209 <<
" in multidomain namespace, " <<
Dim << std::endl;
2211 OOMPH_CURRENT_FUNCTION,
2212 OOMPH_EXCEPTION_LOCATION);
2221 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
2227 for (
unsigned i = 0;
i < el_dim;
i++)
2237 mesh_geom_obj_pt[i_mesh]->locate_zeta(
2238 x_global, sub_geom_obj_pt, s_ext);
2241 if (sub_geom_obj_pt != 0)
2275 #ifdef OOMPH_HAS_MPI
2286 source_finite_el_pt;
2293 #ifdef OOMPH_HAS_MPI
2299 for (
unsigned i = 0;
i < el_dim;
i++)
2314 for (
unsigned i = 0;
i < el_dim;
i++)
2329 for (
unsigned i = 0;
i <
Dim;
i++)
2344 Mesh*
const& mesh_pt,
2345 Mesh*
const& external_mesh_pt)
2347 #ifdef OOMPH_HAS_MPI
2353 unsigned mesh_dim = 0;
2358 unsigned external_mesh_dim = 0;
2359 if (external_mesh_pt->
nelement() > 0)
2366 #ifdef OOMPH_HAS_MPI
2367 int n_proc = comm_pt->nproc();
2370 unsigned mesh_dim_reduce;
2371 MPI_Allreduce(&mesh_dim,
2376 comm_pt->mpi_comm());
2377 mesh_dim = mesh_dim_reduce;
2379 unsigned external_mesh_dim_reduce;
2380 MPI_Allreduce(&external_mesh_dim,
2381 &external_mesh_dim_reduce,
2385 comm_pt->mpi_comm());
2386 external_mesh_dim = external_mesh_dim_reduce;
2391 if (mesh_dim != external_mesh_dim)
2393 std::ostringstream error_stream;
2394 error_stream <<
"The elements within the two meshes do not\n"
2395 <<
"have the same dimension, so the multi-domain\n"
2396 <<
"method will not work.\n"
2397 <<
"For the mesh, dim=" << mesh_dim
2398 <<
", and the external mesh, dim=" << external_mesh_dim
2401 error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2442 double dist_squared1 = 0.0;
2443 for (
unsigned i = 0;
i <
Dim;
i++)
2454 double dist_squared2 = 0.0;
2455 for (
unsigned i = 0;
i <
Dim;
i++)
2463 if (dist_squared1 < dist_squared2)
////////////////////////////////////////////////////////////////////
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.
unsigned ngeom_object_list_pt()
Return number of geometric objects associated with AlgebraicMesh.
////////////////////////////////////////////////////////////////////
unsigned ngeom_object(const int &id)
Number of geometric objects involved in id-th update function.
unsigned nref_value(const int &id)
Number of reference values involved in id-th update function.
GeomObject * geom_object_pt(const unsigned &i)
Return pointer to i-th geometric object involved in default (usually first) update function.
int node_update_fct_id()
Default (usually first if there are multiple ones) node update fct id.
double ref_value(const unsigned &i)
Return i-th reference value involved in default (usually first) update function.
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.
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
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).
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
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...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
void get_local_coordinate_in_bulk(const Vector< double > &s, Vector< double > &s_bulk) const
Calculate the vector of local coordinate in the bulk element given the local coordinates in this Face...
A general Finite Element class.
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
virtual Node * construct_node(const unsigned &n)
Construct the local node n and return a pointer to the newly created node object.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
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...
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)
MacroElement * macro_elem_pt()
Access function to pointer to macro element.
virtual Node * construct_boundary_node(const unsigned &n)
Construct the local node n as a boundary node; that is a node that MAY be placed on a mesh boundary a...
A Generalised Element class.
bool is_halo() const
Is this element a halo?
/////////////////////////////////////////////////////////////////////
Class that contains data for hanging nodes.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
unsigned nmaster() const
Return the number of master nodes.
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.
////////////////////////////////////////////////////////////////////
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...
Base class for MacroElement s that are used during mesh refinement in domains with curvlinear and/or ...
unsigned & macro_element_number()
Access function to the Macro_element_number.
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 add_external_haloed_node_pt(const unsigned &p, Node *&nod_pt)
Add external haloed node whose halo (external) counterpart is held on processor p to the storage sche...
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 nboundary() const
Return number of boundaries.
unsigned add_external_haloed_element_pt(const unsigned &p, GeneralisedElement *&el_pt)
Add external haloed element whose non-halo counterpart is held on processor p to the storage scheme f...
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
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 nexternal_haloed_node()
Total number of external haloed nodes in this Mesh.
unsigned long nelement() const
Return number of elements in the 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.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
virtual bool is_on_boundary() const
Test whether the Node lies on a boundary. The "bulk" Node cannot lie on a boundary,...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
void resize(const unsigned &n_value)
Resize the number of equations.
unsigned nposition_type() const
Number of coordinate types needed in the mapping between local and global coordinates.
bool is_hanging() const
Test whether the node is geometrically hanging.
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation....
An 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
unsigned ntime_stepper() const
Return the number of time steppers.
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)....
unsigned nlagrangian_type() const
Number of types of Lagrangian coordinates used to interpolate the Lagrangian coordinates within the e...
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
unsigned nlagrangian() const
Return number of lagrangian coordinates.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
A slight extension to the standard template vector class so that we can include "graceful" array rang...
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 get_required_master_nodal_information_helper(int &iproc, Node *master_nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Helper function to get the required master nodal information from an external haloed master node so t...
void clean_up()
Helper function that clears all the information used during the external storage creation.
Vector< unsigned > Flat_packed_unsigneds
Vector of flat-packed unsigneds to be communicated with other processors – this is really "private" d...
Vector< double > Zeta_coords_for_further_away_comparison
Vector of zeta coordinates that we're currently trying to locate; used in sorting of bin entries in f...
bool Doc_timings
Boolean to indicate whether to doc timings or not.
void add_external_haloed_master_node_helper(int &iproc, Node *master_nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Helper function to add external haloed node that is a master.
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...
Vector< std::string > Flat_packed_unsigneds_string
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_node_helper(Node *&new_nod_pt, unsigned &loc_p, unsigned &node_index, FiniteElement *const &new_el_pt, Mesh *const &external_mesh_pt, Problem *problem_pt)
Helper function which constructs a new external halo node (on new element) with the required informat...
bool Allow_use_of_halo_elements_as_external_elements
Boolean to indicate if we're allowed to use halo elements as external elements. Can drastically reduc...
bool Allow_use_of_halo_elements_as_external_elements_for_projection
Indicate whether we are allowed to use halo elements as external elements for projection,...
bool Doc_stats
Boolean to indicate whether to output basic info during setup_multi_domain_interaction() routines.
bool Doc_full_stats
Boolean to indicate whether to output further info during setup_multi_domain_interaction() routines.
Vector< double > Received_flat_packed_zetas_to_be_found
Vector of flat-packed zeta coordinates for which the external element could not be found on another p...
void add_external_haloed_node_helper(int &iproc, Node *nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Helper to add external haloed node that is not a master.
void get_required_nodal_information_helper(int &iproc, Node *nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Helper function to get the required nodal information from an external haloed node so that a fully-fu...
void recursively_add_masters_of_external_haloed_node(int &iproc, Node *nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Recursively add any master nodes (and their master nodes etc) of external nodes.
void add_external_halo_node_helper(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 functiono to add external halo node that is not a master.
bool Use_bulk_element_as_external
Boolean to indicate when to use the bulk element as the external element. Defaults to false,...
bool first_closer_than_second(const std::pair< FiniteElement *, Vector< double >> &p1, const std::pair< FiniteElement *, Vector< double >> &p2)
Comparison function for sorting entries in bin: Returns true if point identified by p1 (comprising po...
Vector< unsigned > Located_element_status
Vector to indicate (to another processor) whether a located element (that will have to represented as...
void add_external_haloed_node_to_storage(int &iproc, Node *nod_pt, Problem *problem_pt, Mesh *const &external_mesh_pt, int &n_cont_inter_values)
Helper function to add external haloed nodes, including any masters.
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....
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...