29 #ifndef OOMPH_REFINEABLE_MESH_TEMPLATE_CC 
   30 #define OOMPH_REFINEABLE_MESH_TEMPLATE_CC 
   34 #include <oomph-lib-config.h> 
   54   template<
class ELEMENT>
 
   56     const unsigned& ncont_interpolated_values)
 
   59     if (is_additional_synchronisation_of_hanging_nodes_disabled() == 
true)
 
   66     using namespace Missing_masters_functions;
 
   78     int n_proc = Comm_pt->nproc();
 
   79     int my_rank = Comm_pt->my_rank();
 
   89     for (
int d = 0; d < n_proc; d++)
 
   94         if (nexternal_haloed_node(d) != 0)
 
   98                      << 
"'s external haloed nodes with processor " << d
 
   99                      << 
" are:" << std::endl;
 
  100           for (
unsigned i = 0; 
i < nexternal_haloed_node(d); 
i++)
 
  102             oomph_info << 
"external_haloed_node_pt(" << d << 
"," << 
i 
  103                        << 
") = " << external_haloed_node_pt(d, 
i) << std::endl;
 
  104             oomph_info << 
"x = ( " << external_haloed_node_pt(d, 
i)->x(0)
 
  105                        << 
" , " << external_haloed_node_pt(d, 
i)->x(1) << 
" )" 
  111     for (
int d = 0; d < n_proc; d++)
 
  116         if (nexternal_halo_node(d) != 0)
 
  120                      << 
"'s external halo nodes with processor " << d
 
  121                      << 
" are:" << std::endl;
 
  122           for (
unsigned i = 0; 
i < nexternal_halo_node(d); 
i++)
 
  124             oomph_info << 
"external_halo_node_pt(" << d << 
"," << 
i 
  125                        << 
") = " << external_halo_node_pt(d, 
i) << std::endl;
 
  126             oomph_info << 
"x = ( " << external_halo_node_pt(d, 
i)->x(0) << 
" , " 
  127                        << external_halo_node_pt(d, 
i)->x(1) << 
" )" 
  135       std::ostringstream err_stream;
 
  136       err_stream << 
"There are already some nodes in the external storage" 
  138                  << 
"for this mesh. This bit assumes that nothing else" 
  140                  << 
"uses this storage (for now).";
 
  142         err_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  164     int ncont_inter_values = ncont_interpolated_values;
 
  168     for (
int d = 0; d < n_proc; d++)
 
  175         unsigned nh = nhaloed_node(d);
 
  176         for (
unsigned j = 0; j < nh; j++)
 
  179           Node* nod_pt = haloed_node_pt(d, j);
 
  183           for (
int icont = -1; icont < ncont_inter_values; icont++)
 
  189               haloed_hanging[d].push_back(n_master);
 
  193               haloed_hanging[d].push_back(0);
 
  199         unsigned count_haloed = haloed_hanging[d].size();
 
  204         MPI_Recv(&tmp, 1, MPI_UNSIGNED, d, 0, Comm_pt->mpi_comm(), &status);
 
  205         if (tmp != count_haloed)
 
  207           std::ostringstream error_stream;
 
  208           error_stream << 
"Number of halo data, " << tmp
 
  209                        << 
", does not match number of haloed data, " 
  210                        << count_haloed << std::endl;
 
  212                               OOMPH_CURRENT_FUNCTION,
 
  213                               OOMPH_EXCEPTION_LOCATION);
 
  218         if (count_haloed != 0)
 
  220           halo_hanging[d].resize(count_haloed);
 
  221           MPI_Recv(&halo_hanging[d][0],
 
  234         for (
int dd = 0; dd < n_proc; dd++)
 
  243             unsigned nh = nhalo_node(dd);
 
  244             for (
unsigned j = 0; j < nh; j++)
 
  247               Node* nod_pt = halo_node_pt(dd, j);
 
  251               for (
int icont = -1; icont < ncont_inter_values; icont++)
 
  257                   local_halo_hanging.push_back(n_master);
 
  261                   local_halo_hanging.push_back(0);
 
  268             unsigned count_halo = local_halo_hanging.size();
 
  272             MPI_Send(&count_halo, 1, MPI_UNSIGNED, dd, 0, Comm_pt->mpi_comm());
 
  278               MPI_Send(&local_halo_hanging[0],
 
  283                        Comm_pt->mpi_comm());
 
  294                     "additional_synchronise_hanging_nodes(): " 
  295                  << t_end - t_start << std::endl;
 
  310     for (
int d = 0; d < n_proc; d++)
 
  319         unsigned nh = nhaloed_node(d);
 
  320         for (
unsigned j = 0; j < nh; j++)
 
  323           Node* nod_pt = haloed_node_pt(d, j);
 
  327           for (
int icont = -1; icont < ncont_inter_values; icont++)
 
  334             if ((haloed_hanging[d][count] > 0) &&
 
  335                 (haloed_hanging[d][count] != halo_hanging[d][count]))
 
  338               haloed_hanging_node_with_discrepancy_pt[d].insert(
 
  339                 std::pair<Node*, unsigned>(nod_pt, d));
 
  355     for (
int d = 0; d < n_proc; d++)
 
  368         unsigned nhaloed_nonmaster_nodes_processed = 0;
 
  372         std::map<Node*, unsigned>::iterator j;
 
  373         for (j = haloed_hanging_node_with_discrepancy_pt[d].begin();
 
  374              j != haloed_hanging_node_with_discrepancy_pt[d].end();
 
  377           Node* nod_pt = (*j).first;
 
  381           std::vector<Node*>::iterator it = std::find(
 
  382             Shared_node_pt[d].begin(), Shared_node_pt[d].end(), nod_pt);
 
  383           if (it != Shared_node_pt[d].end())
 
  387             nhaloed_nonmaster_nodes_processed++;
 
  391             unsigned index = it - Shared_node_pt[d].begin();
 
  392             haloed_nonmaster_node_index.push_back(index);
 
  406             throw OomphLibError(
"Haloed node not found in haloed node storage",
 
  407                                 OOMPH_CURRENT_FUNCTION,
 
  408                                 OOMPH_EXCEPTION_LOCATION);
 
  413         unsigned send_unsigneds_count = send_unsigneds.size();
 
  414         unsigned send_doubles_count = send_doubles.size();
 
  418           &send_unsigneds_count, 1, MPI_UNSIGNED, d, 0, Comm_pt->mpi_comm());
 
  420           &send_doubles_count, 1, MPI_UNSIGNED, d, 1, Comm_pt->mpi_comm());
 
  423         MPI_Send(&nhaloed_nonmaster_nodes_processed,
 
  428                  Comm_pt->mpi_comm());
 
  429         if (nhaloed_nonmaster_nodes_processed > 0)
 
  431           MPI_Send(&haloed_nonmaster_node_index[0],
 
  432                    nhaloed_nonmaster_nodes_processed,
 
  436                    Comm_pt->mpi_comm());
 
  440         if (send_unsigneds_count > 0)
 
  443           MPI_Send(&send_unsigneds[0],
 
  444                    send_unsigneds_count,
 
  448                    Comm_pt->mpi_comm());
 
  450         if (send_doubles_count > 0)
 
  453           MPI_Send(&send_doubles[0],
 
  458                    Comm_pt->mpi_comm());
 
  468         for (
int dd = 0; dd < n_proc; dd++)
 
  474             unsigned nrecv_unsigneds = 0;
 
  475             unsigned nrecv_doubles = 0;
 
  476             MPI_Recv(&nrecv_unsigneds,
 
  483             MPI_Recv(&nrecv_doubles,
 
  493             unsigned nhalo_nonmaster_nodes_to_process = 0;
 
  494             MPI_Recv(&nhalo_nonmaster_nodes_to_process,
 
  502               nhalo_nonmaster_nodes_to_process);
 
  503             if (nhalo_nonmaster_nodes_to_process != 0)
 
  505               MPI_Recv(&halo_nonmaster_node_index[0],
 
  506                        nhalo_nonmaster_nodes_to_process,
 
  519             if (nrecv_unsigneds > 0)
 
  522               MPI_Recv(&recv_unsigneds[0],
 
  530             if (nrecv_doubles > 0)
 
  533               MPI_Recv(&recv_doubles[0],
 
  543             unsigned recv_unsigneds_count = 0;
 
  544             unsigned recv_doubles_count = 0;
 
  547             for (
unsigned j = 0; j < nhalo_nonmaster_nodes_to_process; j++)
 
  551               Node* nod_pt = shared_node_pt(dd, halo_nonmaster_node_index[j]);
 
  563                 std::ostringstream err_stream;
 
  565                   << 
"This currently doesn't work for" << std::endl
 
  566                   << 
"MacroElementNodeUpdateNodes because these require" 
  568                   << 
"MacroElementNodeUpdateElements to be created for" 
  570                   << 
"the missing halo nodes which will be added" << std::endl;
 
  572                                     OOMPH_CURRENT_FUNCTION,
 
  573                                     OOMPH_EXCEPTION_LOCATION);
 
  581               unsigned loc_p = (unsigned)dd;
 
  583               recursively_add_masters_of_external_halo_node_to_storage<ELEMENT>(
 
  589                 recv_unsigneds_count,
 
  604       oomph_info << 
"Time for second all-to-all in " 
  605                     "additional_synchronise_hanging_nodes() " 
  606                  << t_end - t_start << std::endl;
 
  614     unsigned external_halo_count = 0;
 
  615     unsigned external_haloed_count = 0;
 
  621     bool duplicate_haloed_node_exists = 
false;
 
  624     for (
int d = 0; d < n_proc; d++)
 
  628       std::map<Node*, bool> node_shared;
 
  636         unsigned nexternal_halo_nod = nexternal_halo_node(d);
 
  637         for (
unsigned j = 0; j < nexternal_halo_nod; j++)
 
  639           Node* nod_pt = external_halo_node_pt(d, j);
 
  642           if (!node_shared[nod_pt])
 
  644             this->add_shared_node_pt(d, nod_pt);
 
  645             node_shared[nod_pt] = 
true;
 
  646             external_halo_count++;
 
  652         unsigned nexternal_haloed_nod = nexternal_haloed_node(d);
 
  653         for (
unsigned j = 0; j < nexternal_haloed_nod; j++)
 
  655           Node* nod_pt = external_haloed_node_pt(d, j);
 
  658           if (!node_shared[nod_pt])
 
  660             this->add_shared_node_pt(d, nod_pt);
 
  661             node_shared[nod_pt] = 
true;
 
  662             external_haloed_count++;
 
  666             duplicate_haloed_node_exists = 
true;
 
  678         unsigned nexternal_haloed_nod = nexternal_haloed_node(d);
 
  679         for (
unsigned j = 0; j < nexternal_haloed_nod; j++)
 
  681           Node* nod_pt = external_haloed_node_pt(d, j);
 
  684           if (!node_shared[nod_pt])
 
  686             this->add_shared_node_pt(d, nod_pt);
 
  687             node_shared[nod_pt] = 
true;
 
  688             external_haloed_count++;
 
  692             duplicate_haloed_node_exists = 
true;
 
  698         unsigned nexternal_halo_nod = nexternal_halo_node(d);
 
  699         for (
unsigned j = 0; j < nexternal_halo_nod; j++)
 
  701           Node* nod_pt = external_halo_node_pt(d, j);
 
  704           if (!node_shared[nod_pt])
 
  706             this->add_shared_node_pt(d, nod_pt);
 
  707             node_shared[nod_pt] = 
true;
 
  708             external_halo_count++;
 
  719     oomph_info << 
"INFO: " << external_halo_count << 
" external halo nodes and" 
  721     oomph_info << 
"INFO: " << external_haloed_count
 
  722                << 
" external haloed nodes were added to the shared node scheme" 
  726     if (duplicate_haloed_node_exists)
 
  741       std::ostringstream err_stream;
 
  742       err_stream << 
"Duplicate halo nodes exist on another processor!" 
  744                  << 
"(See source code for more detailed explanation)" 
  748         err_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
 
  755       oomph_info << 
"Time for identification of shared nodes in " 
  756                     "additional_synchronise_hanging_nodes(): " 
  757                  << t_end - t_start << std::endl;
 
unsigned nmaster() const
Return the number of master nodes.
 
////////////////////////////////////////////////////////////////////
 
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
 
HangInfo *const  & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
 
bool is_hanging() const
Test whether the node is geometrically hanging.
 
An OomphLibError object which should be thrown when an run-time error is encountered....
 
void additional_synchronise_hanging_nodes(const unsigned &ncont_interpolated_values)
Additional setup of shared node scheme This is Required for reconcilliation of hanging nodes acrross ...
 
A slight extension to the standard template vector class so that we can include "graceful" array rang...
 
bool Doc_comprehensive_timings
Global boolean to switch on comprehensive timing – can probably be declared const false when developm...
 
void recursively_add_masters_of_external_haloed_node(int &iproc, Node *nod_pt, Mesh *const &mesh_pt, int &n_cont_inter_values, Vector< unsigned > &send_unsigneds, Vector< double > &send_doubles)
Recursively add any master nodes (and their master nodes etc) of external nodes.
 
double timer()
returns the time in seconds after some point in past
 
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
 
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...