NonRefineableBinArray Class Reference

NonRefineableBinArray class. More...

#include <sample_point_container.h>

+ Inheritance diagram for NonRefineableBinArray:

Public Member Functions

 NonRefineableBinArray (SamplePointContainerParameters *bin_array_parameters_pt)
 Constructor. More...
 
 ~NonRefineableBinArray ()
 Destructor: More...
 
 NonRefineableBinArray (const NonRefineableBinArray &data)=delete
 Broken copy constructor. More...
 
void operator= (const NonRefineableBinArray &)=delete
 Broken assignment operator. More...
 
void locate_zeta (const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s)
 
unsigned nbin () const
 Total number of bins (empty or not) More...
 
unsigned total_number_of_sample_points_computed_recursively () const
 Compute total number of sample points recursively. More...
 
unsigned n_spiral_chunk () const
 Number of spirals to be searched in one go const version. More...
 
unsignedn_spiral_chunk ()
 Number of spirals to be searched in one go. More...
 
unsignedmax_spiral_level ()
 
unsignedcurrent_min_spiral_level ()
 Access function to current min. spiral level. More...
 
unsignedcurrent_max_spiral_level ()
 Access function to current max. spiral level. More...
 
void get_fill_stats (unsigned &n_bin, unsigned &max_n_entry, unsigned &min_n_entry, unsigned &tot_n_entry, unsigned &n_empty) const
 Provide some stats on the fill level of the associated bin. More...
 
double min_distance (const unsigned &i_bin, const Vector< double > &zeta)
 
void output_bin_vertices (std::ofstream &outfile)
 Output bin vertices (allowing display of bins as zones). More...
 
void get_bin_vertices (const unsigned &i_bin, Vector< Vector< double >> &bin_vertex)
 
void get_bin (const Vector< double > &zeta, int &bin_number)
 
void get_bin (const Vector< double > &zeta, int &bin_number, Vector< std::pair< FiniteElement *, Vector< double >>> &sample_point_pairs)
 
Vector< Vector< std::pair< FiniteElement *, Vector< double > > > > bin_content () const
 Get the contents of all bins in vector. More...
 
const std::map< unsigned, Vector< std::pair< FiniteElement *, Vector< double > > > > * get_all_bins_content () const
 Get the contents of all bins in vector. More...
 
void fill_bin_by_diffusion (const unsigned &bin_diffusion_radius=1)
 
void output_bins (std::ofstream &outfile)
 Output bins. More...
 
void output_bins (std::string &filename)
 Output bins. More...
 
- Public Member Functions inherited from BinArray
 BinArray (Mesh *mesh_pt, const Vector< std::pair< double, double >> &min_and_max_coordinates, const Vector< unsigned > &dimensions_of_bin_array, const bool &use_eulerian_coordinates_during_setup, const bool &ignore_halo_elements_during_locate_zeta_search, const unsigned &nsample_points_generated_per_element)
 Constructor. More...
 
 BinArray ()
 
 BinArray (const BinArray &data)=delete
 Broken copy constructor. More...
 
void operator= (const BinArray &)=delete
 Broken assignment operator. More...
 
virtual ~BinArray ()
 Virtual destructor. More...
 
void get_neighbouring_bins_helper (const unsigned &bin_index, const unsigned &radius, Vector< unsigned > &neighbouring_bin_index, const bool &use_old_version=true)
 
void profile_get_neighbouring_bins_helper ()
 
unsigned coords_to_bin_index (const Vector< double > &zeta)
 
void coords_to_vectorial_bin_index (const Vector< double > &zeta, Vector< unsigned > &bin_index)
 Get "coordinates" of bin that contains specified zeta. More...
 
unsigned max_bin_dimension () const
 Max. bin dimension (number of bins in coordinate directions) More...
 
unsigned ndim_zeta () const
 Dimension of the zeta ( = dim of local coordinate of elements) More...
 
unsigned dimension_of_bin_array (const unsigned &i) const
 Number of bins in coordinate direction i. More...
 
Vector< unsigneddimensions_of_bin_array () const
 
unsigned dimensions_of_bin_array (const unsigned &i) const
 Number of bins in specified coordinate direction. More...
 
- Public Member Functions inherited from SamplePointContainer
 SamplePointContainer (Mesh *mesh_pt, const Vector< std::pair< double, double >> &min_and_max_coordinates, const bool &use_eulerian_coordinates_during_setup, const bool &ignore_halo_elements_during_locate_zeta_search, const unsigned &nsample_points_generated_per_element)
 Constructor. More...
 
 SamplePointContainer ()
 
 SamplePointContainer (const SamplePointContainer &data)=delete
 Broken copy constructor. More...
 
void operator= (const SamplePointContainer &)=delete
 Broken assignment operator. More...
 
virtual ~SamplePointContainer ()
 Virtual destructor. More...
 
virtual unsignedtotal_number_of_sample_points_visited_during_locate_zeta_from_top_level ()
 
Mesh * mesh_pt () const
 Pointer to mesh from whose FiniteElements sample points are created. More...
 
const std::pair< double, double > & min_and_max_coordinates (const unsigned &i) const
 
const Vector< std::pair< double, double > > & min_and_max_coordinates () const
 
bool use_eulerian_coordinates_during_setup () const
 
unsignednsample_points_generated_per_element ()
 "Measure of" number of sample points generated in each element More...
 
doublemax_search_radius ()
 

Static Public Attributes

static unsigned Default_n_bin_1d = 100
 Default number of bins (in each coordinate direction) More...
 
static unsigned long Total_nbin_cells_counter = 0
 
static unsigned long Threshold_for_total_bin_cell_number_warning
 
static bool Suppress_warning_about_large_total_number_of_bins
 Boolean to supppress warnings about large number of bins. More...
 
static bool Already_warned_about_large_number_of_bin_cells
 
static unsigned Threshold_for_elements_per_bin_warning = 100
 
static bool Suppress_warning_about_small_number_of_bins
 Boolean to supppress warnings about small number of bins. More...
 
static bool Already_warned_about_small_number_of_bin_cells
 
- Static Public Attributes inherited from SamplePointContainer
static std::ofstream Visited_sample_points_file
 File to record sequence of visited sample points in. More...
 
static bool Always_fail_elemental_locate_zeta = false
 Boolean flag to make to make locate zeta fail. More...
 
static bool Use_equally_spaced_interior_sample_points = true
 
static bool Enable_timing_of_setup = false
 Time setup? More...
 
static double Percentage_offset = 5.0
 Offset of sample point container boundaries beyond max/min coords. More...
 

Private Member Functions

void fill_bin_array ()
 Fill the bin array with sample points from FiniteElements stored in mesh. More...
 
void create_bins_of_objects ()
 
void flush_bins_of_objects ()
 

Private Attributes

SparseVector< Vector< std::pair< FiniteElement *, Vector< double > > > > Bin_object_coord_pairs
 Storage for paired objects and coords in each bin. More...
 
unsigned Max_spiral_level
 
unsigned Current_min_spiral_level
 Current min. spiralling level. More...
 
unsigned Current_max_spiral_level
 Current max. spiralling level. More...
 
unsigned Nspiral_chunk
 Number of spirals to be searched in one go. More...
 

Additional Inherited Members

- Protected Member Functions inherited from SamplePointContainer
void setup_min_and_max_coordinates ()
 Setup the min and max coordinates for the mesh, in each dimension. More...
 
- Protected Attributes inherited from BinArray
Vector< unsignedDimensions_of_bin_array
 Number of bins in each coordinate direction. More...
 
- Protected Attributes inherited from SamplePointContainer
Mesh * Mesh_pt
 Pointer to mesh from whose FiniteElements sample points are created. More...
 
Vector< std::pair< double, double > > Min_and_max_coordinates
 
bool Use_eulerian_coordinates_during_setup
 
unsigned Nsample_points_generated_per_element
 "Measure of" number of sample points generated in each element More...
 
unsigned Total_number_of_sample_points_visited_during_locate_zeta_from_top_level
 
double Max_search_radius
 

Detailed Description

NonRefineableBinArray class.

///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

Constructor & Destructor Documentation

◆ NonRefineableBinArray() [1/2]

NonRefineableBinArray::NonRefineableBinArray ( SamplePointContainerParameters *  sample_point_container_parameters_pt)

Constructor.

///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

2172  sample_point_container_parameters_pt->mesh_pt(),
2173  sample_point_container_parameters_pt->min_and_max_coordinates(),
2174  sample_point_container_parameters_pt
2175  ->use_eulerian_coordinates_during_setup(),
2176  sample_point_container_parameters_pt
2177  ->ignore_halo_elements_during_locate_zeta_search(),
2178  sample_point_container_parameters_pt
2179  ->nsample_points_generated_per_element()),
2180  BinArray(
2181  sample_point_container_parameters_pt->mesh_pt(),
2182  sample_point_container_parameters_pt->min_and_max_coordinates(),
2183  dynamic_cast<BinArrayParameters*>(sample_point_container_parameters_pt)
2184  ->dimensions_of_bin_array(),
2185  sample_point_container_parameters_pt
2186  ->use_eulerian_coordinates_during_setup(),
2187  sample_point_container_parameters_pt
2188  ->ignore_halo_elements_during_locate_zeta_search(),
2189  sample_point_container_parameters_pt
2190  ->nsample_points_generated_per_element())
2191  {
2192  // Set default size of bin array (and spatial dimension!)
2193  if (Dimensions_of_bin_array.size() == 0)
2194  {
2195  int dim = 0;
2196  if (Mesh_pt->nelement() != 0)
2197  {
2198  dim = Mesh_pt->finite_element_pt(0)->dim();
2199  }
2200 
2201 
2202  // Need to do an Allreduce to ensure that the dimension is consistent
2203  // even when no elements are assigned to a certain processor
2204 #ifdef OOMPH_HAS_MPI
2205  // Only a problem if the mesh has been distributed
2206  if (Mesh_pt->is_mesh_distributed())
2207  {
2208  // Need a non-null communicator
2209  if (Mesh_pt->communicator_pt() != 0)
2210  {
2211  int n_proc = Mesh_pt->communicator_pt()->nproc();
2212  if (n_proc > 1)
2213  {
2214  int dim_reduce;
2215  MPI_Allreduce(&dim,
2216  &dim_reduce,
2217  1,
2218  MPI_INT,
2219  MPI_MAX,
2220  Mesh_pt->communicator_pt()->mpi_comm());
2221  dim = dim_reduce;
2222  }
2223  }
2224  }
2225 #endif
2226 
2228  }
2229 
2230  // Have we specified max/min coordinates?
2231  // If not, compute them on the fly from mesh
2232  if (Min_and_max_coordinates.size() == 0)
2233  {
2235  }
2236 
2237  // Spiraling parameters
2238  Max_spiral_level = UINT_MAX;
2240 
2241  NonRefineableBinArrayParameters* non_ref_bin_array_parameters_pt =
2242  dynamic_cast<NonRefineableBinArrayParameters*>(
2243  sample_point_container_parameters_pt);
2244 
2245 #ifdef PARANOID
2246  if (non_ref_bin_array_parameters_pt == 0)
2247  {
2248  throw OomphLibError("Wrong sample_point_container_parameters_pt",
2251  }
2252 #endif
2253 
2254  Nspiral_chunk = non_ref_bin_array_parameters_pt->nspiral_chunk();
2256 
2257  // Time it
2258  double t_start = 0.0;
2260  {
2261  t_start = TimingHelpers::timer();
2262  }
2263 
2264  // Now fill the bastard...
2265  fill_bin_array();
2266 
2268  {
2269  double t_end = TimingHelpers::timer();
2271  oomph_info << "Time for setup of " << Dimensions_of_bin_array.size()
2272  << "-dimensional sample point container containing " << npts
2273  << " sample points: " << t_end - t_start
2274  << " sec (non-ref_bin); third party: 0 sec ( = 0 %)"
2275  << std::endl;
2276  }
2277  }
unsigned max_bin_dimension() const
Max. bin dimension (number of bins in coordinate directions)
Definition: sample_point_container.cc:659
Vector< unsigned > Dimensions_of_bin_array
Number of bins in each coordinate direction.
Definition: sample_point_container.h:508
BinArray()
Definition: sample_point_container.h:425
void fill_bin_array()
Fill the bin array with sample points from FiniteElements stored in mesh.
Definition: sample_point_container.cc:2402
unsigned Nspiral_chunk
Number of spirals to be searched in one go.
Definition: sample_point_container.h:1025
unsigned Max_spiral_level
Definition: sample_point_container.h:1016
unsigned Current_min_spiral_level
Current min. spiralling level.
Definition: sample_point_container.h:1019
unsigned Current_max_spiral_level
Current max. spiralling level.
Definition: sample_point_container.h:1022
unsigned total_number_of_sample_points_computed_recursively() const
Compute total number of sample points recursively.
Definition: sample_point_container.cc:2284
static unsigned Default_n_bin_1d
Default number of bins (in each coordinate direction)
Definition: sample_point_container.h:860
Vector< std::pair< double, double > > Min_and_max_coordinates
Definition: sample_point_container.h:363
static bool Enable_timing_of_setup
Time setup?
Definition: sample_point_container.h:346
SamplePointContainer()
Definition: sample_point_container.h:233
Mesh * Mesh_pt
Pointer to mesh from whose FiniteElements sample points are created.
Definition: sample_point_container.h:357
void setup_min_and_max_coordinates()
Setup the min and max coordinates for the mesh, in each dimension.
Definition: sample_point_container.cc:684
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
double timer
Definition: oomph_metis_from_parmetis_3.1.1/struct.h:210

References Current_max_spiral_level, Current_min_spiral_level, Default_n_bin_1d, BinArray::Dimensions_of_bin_array, SamplePointContainer::Enable_timing_of_setup, fill_bin_array(), BinArray::max_bin_dimension(), Max_spiral_level, SamplePointContainer::Mesh_pt, SamplePointContainer::Min_and_max_coordinates, Nspiral_chunk, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, SamplePointContainer::setup_min_and_max_coordinates(), and total_number_of_sample_points_computed_recursively().

◆ ~NonRefineableBinArray()

NonRefineableBinArray::~NonRefineableBinArray ( )
inline

Destructor:

827  {
829  }
void flush_bins_of_objects()
Definition: sample_point_container.h:1004

References flush_bins_of_objects().

◆ NonRefineableBinArray() [2/2]

NonRefineableBinArray::NonRefineableBinArray ( const NonRefineableBinArray data)
delete

Broken copy constructor.

Member Function Documentation

◆ bin_content()

Vector<Vector<std::pair<FiniteElement*, Vector<double> > > > NonRefineableBinArray::bin_content ( ) const
inline

Get the contents of all bins in vector.

931  {
932  Vector<Vector<std::pair<FiniteElement*, Vector<double>>>> all_vals;
933  Bin_object_coord_pairs.get_all_values(all_vals);
934  return all_vals;
935  }
SparseVector< Vector< std::pair< FiniteElement *, Vector< double > > > > Bin_object_coord_pairs
Storage for paired objects and coords in each bin.
Definition: sample_point_container.h:1012

References Bin_object_coord_pairs.

◆ create_bins_of_objects()

void NonRefineableBinArray::create_bins_of_objects ( )
private

Initialise and populate the "bin" structure for locating coordinates and increment counter for total number of bins in active use by any MeshAsGeomObject)

◆ current_max_spiral_level()

unsigned& NonRefineableBinArray::current_max_spiral_level ( )
inline

Access function to current max. spiral level.

892  {
894  }

References Current_max_spiral_level.

Referenced by oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), check_locate_zeta(), and locate_zeta().

◆ current_min_spiral_level()

unsigned& NonRefineableBinArray::current_min_spiral_level ( )
inline

Access function to current min. spiral level.

886  {
888  }

References Current_min_spiral_level.

Referenced by oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), check_locate_zeta(), and locate_zeta().

◆ fill_bin_array()

void NonRefineableBinArray::fill_bin_array ( )
private

Fill the bin array with sample points from FiniteElements stored in mesh.

Loop over subobjects (elements) to decide which bin they belong in...

2403  {
2404  // Store the lagrangian dimension
2405  const unsigned n_lagrangian = this->ndim_zeta();
2406 
2407  // Flush all objects out of the bin structure
2409 
2410  // Temporary storage in bin
2411  std::map<unsigned, Vector<std::pair<FiniteElement*, Vector<double>>>>
2412  tmp_bin_object_coord_pairs;
2413 
2414  // Total number of bins
2415  unsigned ntotalbin = nbin();
2416 
2417  // Initialise the structure that keep tracks of the occupided bins
2418  Bin_object_coord_pairs.initialise(ntotalbin);
2419 
2420 
2421  // Issue warning about small number of bins
2423  {
2424  // Calculate the (nearest integer) number of elements per bin
2425  unsigned n_mesh_element = Mesh_pt->nelement();
2426  unsigned elements_per_bin = n_mesh_element / ntotalbin;
2427  // If it is above the threshold then issue a warning
2428  if (elements_per_bin > Threshold_for_elements_per_bin_warning)
2429  {
2431  {
2433  std::ostringstream warn_message;
2434  warn_message
2435  << "The average (integer) number of elements per bin is \n\n"
2436  << elements_per_bin << ", which is more than \n\n"
2437  << " "
2438  "NonRefineableBinArray::Threshold_for_elements_per_bin_warning="
2440  << "\n\nIf the lookup seems slow (and you have the memory),"
2441  << "consider increasing\n"
2442  << "BinArray::Dimensions_of_bin_array from their current\n"
2443  << "values of { ";
2444  unsigned nn = Dimensions_of_bin_array.size();
2445  for (unsigned ii = 0; ii < nn; ii++)
2446  {
2447  warn_message << Dimensions_of_bin_array[ii] << " ";
2448  }
2449  warn_message
2450  << " }.\n"
2451  << "\nNOTE: You can suppress this warning by increasing\n\n"
2452  << " NonRefineableBinArray::"
2453  << "Threshold_for_elements_per_bin_warning\n\n"
2454  << "or by setting \n\n "
2455  << "NonRefineableBinArray::Suppress_warning_about_small_number_of_"
2456  "bins\n\n"
2457  << "to true (both are public static data).\n\n";
2458  OomphLibWarning(warn_message.str(),
2461  }
2462  }
2463  }
2464 
2465 
2466  // Increase overall counter
2467  Total_nbin_cells_counter += ntotalbin;
2468 
2469 
2470  // Issue warning?
2472  {
2475  {
2477  {
2479  std::ostringstream warn_message;
2480  warn_message
2481  << "Have allocated \n\n"
2482  << " NonRefineableBinArray::Total_nbin_cells_counter="
2484  << "\n\nbin cells, which is more than \n\n"
2485  << " NonRefineableBinArray::"
2486  << "Threshold_for_total_bin_cell_number_warning="
2487  << NonRefineableBinArray::
2488  Threshold_for_total_bin_cell_number_warning
2489  << "\n\nIf you run out of memory, consider reducing\n"
2490  << "BinArray::Dimensions_of_bin_array from their current\n"
2491  << "values of { ";
2492  unsigned nn = Dimensions_of_bin_array.size();
2493  for (unsigned ii = 0; ii < nn; ii++)
2494  {
2495  warn_message << Dimensions_of_bin_array[ii] << " ";
2496  }
2497  warn_message
2498  << " }.\n"
2499  << "\nNOTE: You can suppress this warning by increasing\n\n"
2500  << " NonRefineableBinArray::"
2501  << "Threshold_for_total_bin_cell_number_warning\n\n"
2502  << "or by setting \n\n NonRefineableBinArray::"
2503  << "Suppress_warning_about_large_total_number_of_bins\n\n"
2504  << "to true (both are public static data).\n\n"
2505  << "NOTE: I'll only issue this warning once -- total number of\n"
2506  << "bins may grow yet further!\n";
2507  OomphLibWarning(warn_message.str(),
2510  }
2511  }
2512  }
2513 
2515  unsigned n_sub = Mesh_pt->nelement();
2516  for (unsigned e = 0; e < n_sub; e++)
2517  {
2518  // Cast to the element (sub-object) first
2519  FiniteElement* el_pt =
2520  dynamic_cast<FiniteElement*>(Mesh_pt->finite_element_pt(e));
2521 
2522  // Get specified number of points within the element
2523  unsigned n_plot_points =
2524  el_pt->nplot_points(Nsample_points_generated_per_element);
2525 
2526  for (unsigned iplot = 0; iplot < n_plot_points; iplot++)
2527  {
2528  // Storage for local and global coordinates
2529  Vector<double> local_coord(n_lagrangian, 0.0);
2530  Vector<double> global_coord(n_lagrangian, 0.0);
2531 
2532  // Get local coordinate and interpolate to global
2533  bool use_equally_spaced_interior_sample_points =
2535  el_pt->get_s_plot(iplot,
2537  local_coord,
2538  use_equally_spaced_interior_sample_points);
2539 
2540  // Now get appropriate global coordinate
2542  {
2543  el_pt->interpolated_x(local_coord, global_coord);
2544  }
2545  else
2546  {
2547  el_pt->interpolated_zeta(local_coord, global_coord);
2548  }
2549 
2550  // Which bin are the global coordinates in?
2551  unsigned bin_number = 0;
2552  unsigned multiplier = 1;
2553  // Loop over the dimension
2554  for (unsigned i = 0; i < n_lagrangian; i++)
2555  {
2556 #ifdef PARANOID
2557  if ((global_coord[i] < Min_and_max_coordinates[i].first) ||
2558  (global_coord[i] > Min_and_max_coordinates[i].second))
2559  {
2560  std::ostringstream error_message;
2561  error_message
2562  << "Bin sample point " << iplot << " in element " << e << "\n"
2563  << "is outside bin limits in coordinate direction " << i << ":\n"
2564  << "Sample point coordinate: " << global_coord[i] << "\n"
2565  << "Max bin coordinate : "
2566  << Min_and_max_coordinates[i].second << "\n"
2567  << "Min bin coordinate : " << Min_and_max_coordinates[i].first
2568  << "\n"
2569  << "You should either setup the bin boundaries manually\n"
2570  << "or increase the percentage offset by which the\n"
2571  << "automatically computed bin limits are increased \n"
2572  << "beyond their sampled max/mins. This is defined in\n"
2573  << "the (public) namespace member\n\n"
2574  << "SamplePointContainer::Percentage_offset \n\n which \n"
2575  << "currently has the value: "
2577  throw OomphLibError(error_message.str(),
2580  }
2581 
2582 #endif
2583  unsigned bin_number_i =
2585  ((global_coord[i] - Min_and_max_coordinates[i].first) /
2586  (Min_and_max_coordinates[i].second -
2587  Min_and_max_coordinates[i].first)));
2588 
2589  // Buffer the case when the global coordinate is the maximum
2590  // value
2591  if (bin_number_i == Dimensions_of_bin_array[i])
2592  {
2593  bin_number_i -= 1;
2594  }
2595 
2596  // Add to the bin number
2597  bin_number += multiplier * bin_number_i;
2598 
2599  // Sort out the multiplier
2601  }
2602 
2603  // Add element-sample local coord pair to the calculated bin
2604  tmp_bin_object_coord_pairs[bin_number].push_back(
2605  std::make_pair(el_pt, local_coord));
2606  }
2607  }
2608 
2609  // Finally copy filled vectors across -- wiping memory from temporary
2610  // map as we go along is good and wouldn't be possible if we
2611  // filled the SparseVector's internal map within that class.
2612  typedef std::map<
2613  unsigned,
2614  Vector<std::pair<FiniteElement*, Vector<double>>>>::iterator IT;
2615  for (IT it = tmp_bin_object_coord_pairs.begin();
2616  it != tmp_bin_object_coord_pairs.end();
2617  it++)
2618  {
2619  Bin_object_coord_pairs.set_value((*it).first, (*it).second);
2620  // Make space immediately
2621  (*it).second.clear();
2622  }
2623  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
unsigned ndim_zeta() const
Dimension of the zeta ( = dim of local coordinate of elements)
Definition: sample_point_container.h:480
static bool Already_warned_about_small_number_of_bin_cells
Definition: sample_point_container.h:991
static bool Suppress_warning_about_large_total_number_of_bins
Boolean to supppress warnings about large number of bins.
Definition: sample_point_container.h:976
static unsigned long Total_nbin_cells_counter
Definition: sample_point_container.h:967
static unsigned Threshold_for_elements_per_bin_warning
Definition: sample_point_container.h:984
static bool Suppress_warning_about_small_number_of_bins
Boolean to supppress warnings about small number of bins.
Definition: sample_point_container.h:987
static bool Already_warned_about_large_number_of_bin_cells
Definition: sample_point_container.h:980
static unsigned long Threshold_for_total_bin_cell_number_warning
Definition: sample_point_container.h:973
unsigned nbin() const
Total number of bins (empty or not)
Definition: sample_point_container.h:845
static double Percentage_offset
Offset of sample point container boundaries beyond max/min coords.
Definition: sample_point_container.h:349
unsigned Nsample_points_generated_per_element
"Measure of" number of sample points generated in each element
Definition: sample_point_container.h:377
bool Use_eulerian_coordinates_during_setup
Definition: sample_point_container.h:367
static bool Use_equally_spaced_interior_sample_points
Definition: sample_point_container.h:343
return int(ret)+1
double multiplier(const Vector< double > &xi)
Definition: disk_oscillation.cc:63

References Already_warned_about_large_number_of_bin_cells, Already_warned_about_small_number_of_bin_cells, Bin_object_coord_pairs, BinArray::Dimensions_of_bin_array, e(), flush_bins_of_objects(), i, int(), SamplePointContainer::Mesh_pt, SamplePointContainer::Min_and_max_coordinates, Global_Physical_Variables::multiplier(), nbin(), BinArray::ndim_zeta(), SamplePointContainer::Nsample_points_generated_per_element, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, SamplePointContainer::Percentage_offset, Suppress_warning_about_large_total_number_of_bins, Suppress_warning_about_small_number_of_bins, Threshold_for_elements_per_bin_warning, Threshold_for_total_bin_cell_number_warning, Total_nbin_cells_counter, SamplePointContainer::Use_equally_spaced_interior_sample_points, and SamplePointContainer::Use_eulerian_coordinates_during_setup.

Referenced by NonRefineableBinArray().

◆ fill_bin_by_diffusion()

void NonRefineableBinArray::fill_bin_by_diffusion ( const unsigned bin_diffusion_radius = 1)

Fill bin by diffusion, populating each empty bin with the same content as the first non-empty bin found during a spiral-based search up to the specified "radius" (default 1)

2669  {
2670  // oomph_info << "PROFILING GET_NEIGHBOURING_BINS_HELPER():" << std::endl;
2671  // profile_get_neighbouring_bins_helper();
2672 
2673  // Loop over all bins to check if they're empty
2674  std::list<unsigned> empty_bins;
2675  unsigned n_bin = nbin();
2676  std::vector<bool> was_empty_until_current_iteration(n_bin, false);
2677  for (unsigned i = 0; i < n_bin; i++)
2678  {
2679  if (Bin_object_coord_pairs[i].size() == 0)
2680  {
2681  empty_bins.push_front(i);
2682  was_empty_until_current_iteration[i] = true;
2683  }
2684  }
2685 
2686  // Now keep processing the empty bins until there are none left
2687  unsigned iter = 0;
2688  Vector<unsigned> newly_filled_bin;
2689  while (empty_bins.size() != 0)
2690  {
2691  newly_filled_bin.clear();
2692  newly_filled_bin.reserve(empty_bins.size());
2693  for (std::list<unsigned>::iterator it = empty_bins.begin();
2694  it != empty_bins.end();
2695  it++)
2696  {
2697  unsigned bin = (*it);
2698 
2699  // Look for immediate neighbours within the specified "bin radius"
2700  unsigned level = bin_diffusion_radius;
2701  Vector<unsigned> neighbour_bin;
2702  get_neighbouring_bins_helper(bin, level, neighbour_bin);
2703  unsigned n_neigh = neighbour_bin.size();
2704 
2705  // Find closest pair
2706  double min_dist = DBL_MAX;
2707  std::pair<FiniteElement*, Vector<double>> closest_pair;
2708  for (unsigned i = 0; i < n_neigh; i++)
2709  {
2710  unsigned neigh_bin = neighbour_bin[i];
2711 
2712  // Only allow to re-populate from bins that were already filled at
2713  // previous iteration, otherwise things can progate too fast
2714  if (!was_empty_until_current_iteration[neigh_bin])
2715  {
2716  unsigned nbin_content = Bin_object_coord_pairs[neigh_bin].size();
2717  for (unsigned j = 0; j < nbin_content; j++)
2718  {
2719  FiniteElement* el_pt = Bin_object_coord_pairs[neigh_bin][j].first;
2720  Vector<double> s(Bin_object_coord_pairs[neigh_bin][j].second);
2721  Vector<double> x(2);
2722  el_pt->interpolated_x(s, x);
2723  // Get minimum distance of sample point from any of the vertices
2724  // of current bin
2725  // hierher Louis questions if this is the right thing to do!
2726  // Matthias agrees
2727  // with him but hasn't done anything yet...
2728  // should use the distance to the centre of gravity of
2729  // the empty bin instead!
2730  double dist = min_distance(bin, x);
2731  if (dist < min_dist)
2732  {
2733  min_dist = dist;
2734  closest_pair = Bin_object_coord_pairs[neigh_bin][j];
2735  }
2736  }
2737  }
2738  }
2739 
2740  // Have we filled the bin?
2741  if (min_dist != DBL_MAX)
2742  {
2743  Vector<std::pair<FiniteElement*, Vector<double>>> new_entry;
2744  new_entry.push_back(closest_pair);
2745  Bin_object_coord_pairs.set_value(bin, new_entry);
2746 
2747  // Record that we've filled it.
2748  newly_filled_bin.push_back(bin);
2749 
2750  // Wipe entry without breaking the linked list (Andrew's trick --
2751  // nice!)
2752  std::list<unsigned>::iterator it_to_be_deleted = it;
2753  it--;
2754  empty_bins.erase(it_to_be_deleted);
2755  }
2756  }
2757 
2758  // Get ready for next iteration on remaining empty bins
2759  iter++;
2760  // Now update the vector that records which bins were empty up to now
2761  unsigned n = newly_filled_bin.size();
2762  for (unsigned i = 0; i < n; i++)
2763  {
2764  was_empty_until_current_iteration[newly_filled_bin[i]] = false;
2765  }
2766  }
2767 
2768 
2769 #ifdef PARANOID
2770  // Loop over all bins to check if they're empty
2771  n_bin = nbin();
2772  for (unsigned i = 0; i < n_bin; i++)
2773  {
2774  if (Bin_object_coord_pairs[i].size() == 0)
2775  {
2776  std::ostringstream error_message_stream;
2777  error_message_stream << "Bin " << i << " is still empty\n"
2778  << "after trying to fill it by diffusion\n";
2779  throw OomphLibError(error_message_stream.str(),
2782  }
2783  }
2784 
2785 #endif
2786  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
void get_neighbouring_bins_helper(const unsigned &bin_index, const unsigned &radius, Vector< unsigned > &neighbouring_bin_index, const bool &use_old_version=true)
Definition: sample_point_container.cc:1350
double min_distance(const unsigned &i_bin, const Vector< double > &zeta)
Definition: sample_point_container.cc:3057
RealScalar s
Definition: level1_cplx_impl.h:130
list x
Definition: plotDoE.py:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References Bin_object_coord_pairs, BinArray::get_neighbouring_bins_helper(), i, j, min_distance(), n, nbin(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, s, size, and plotDoE::x.

◆ flush_bins_of_objects()

void NonRefineableBinArray::flush_bins_of_objects ( )
inlineprivate

Flush the storage for the binning method (and decrement counter for total number of bins in active use by any MeshAsGeomObject)

1005  {
1007  Bin_object_coord_pairs.clear();
1008  }

References Bin_object_coord_pairs, and Total_nbin_cells_counter.

Referenced by fill_bin_array(), and ~NonRefineableBinArray().

◆ get_all_bins_content()

const std::map<unsigned, Vector<std::pair<FiniteElement*, Vector<double> > > >* NonRefineableBinArray::get_all_bins_content ( ) const
inline

Get the contents of all bins in vector.

940  {
941  // Return the content of the bins
942  return Bin_object_coord_pairs.map_pt();
943  }

References Bin_object_coord_pairs.

◆ get_bin() [1/2]

void NonRefineableBinArray::get_bin ( const Vector< double > &  zeta,
int bin_number 
)

Get the number of the bin containing the specified coordinate. Bin number is negative if the coordinate is outside the bin structure.

2796  {
2797  // Default for point not found
2798  bin_number = -1;
2799 
2800  // Get the lagrangian dimension
2801  const unsigned n_lagrangian = this->ndim_zeta();
2802 
2803  // Does the zeta coordinate lie within the current bin structure?
2804 
2805  // Loop over the lagrangian dimension
2806  for (unsigned i = 0; i < n_lagrangian; i++)
2807  {
2808  // If the i-th coordinate is less than the minimum
2809  if (zeta[i] < Min_and_max_coordinates[i].first)
2810  {
2811  return;
2812  }
2813  // Otherwise coordinate may be bigger than the maximum
2814  else if (zeta[i] > Min_and_max_coordinates[i].second)
2815  {
2816  return;
2817  }
2818  }
2819 
2820  // Use the min and max coords of the bin structure, to find
2821  // the bin structure containing the current zeta cooordinate
2822 
2823  // Initialise for subsequent computation
2824  bin_number = 0;
2825 
2826  // Offset for rows/matrices in higher dimensions
2827  unsigned multiplier = 1;
2828 
2829  // Loop over the dimension
2830  for (unsigned i = 0; i < n_lagrangian; i++)
2831  {
2832  // Find the bin number of the current coordinate
2833  unsigned bin_number_i =
2835  ((zeta[i] - Min_and_max_coordinates[i].first) /
2836  (Min_and_max_coordinates[i].second -
2837  Min_and_max_coordinates[i].first)));
2838  // Buffer the case when we are exactly on the edge
2839  if (bin_number_i == Dimensions_of_bin_array[i])
2840  {
2841  bin_number_i -= 1;
2842  }
2843  // Now add to the bin number using the multiplier
2844  bin_number += multiplier * bin_number_i;
2845  // Increase the current row/matrix multiplier for the next loop
2847  }
2848 
2849 
2850 #ifdef PARANOID
2851 
2852  // Tolerance for "out of bin" test
2853  double tol = 1.0e-10;
2854 
2855  unsigned nvertex = (int)pow(2, n_lagrangian);
2856  Vector<Vector<double>> bin_vertex(nvertex);
2857  for (unsigned j = 0; j < nvertex; j++)
2858  {
2859  bin_vertex[j].resize(n_lagrangian);
2860  }
2861  get_bin_vertices(bin_number, bin_vertex);
2862  for (unsigned i = 0; i < n_lagrangian; i++)
2863  {
2864  double min_vertex_coord = DBL_MAX;
2865  double max_vertex_coord = -DBL_MAX;
2866  for (unsigned j = 0; j < nvertex; j++)
2867  {
2868  if (bin_vertex[j][i] < min_vertex_coord)
2869  {
2870  min_vertex_coord = bin_vertex[j][i];
2871  }
2872  if (bin_vertex[j][i] > max_vertex_coord)
2873  {
2874  max_vertex_coord = bin_vertex[j][i];
2875  }
2876  }
2877  if (zeta[i] < min_vertex_coord - tol)
2878  {
2879  std::ostringstream error_message_stream;
2880  error_message_stream
2881  << "Trouble! " << i << " -th coordinate of sample point, " << zeta[i]
2882  << " , isn't actually between limits, " << min_vertex_coord << " and "
2883  << max_vertex_coord << " [it's below by more than " << tol << " !] "
2884  << std::endl;
2885  throw OomphLibError(error_message_stream.str(),
2888  }
2889 
2890  if (zeta[i] > max_vertex_coord + tol)
2891  {
2892  std::ostringstream error_message_stream;
2893  error_message_stream
2894  << "Trouble! " << i << " -th coordinate of sample point, " << zeta[i]
2895  << " , isn't actually between limits, " << min_vertex_coord << " and "
2896  << max_vertex_coord << " [it's above by more than " << tol << "!] "
2897  << std::endl;
2898  throw OomphLibError(error_message_stream.str(),
2901  }
2902  }
2903 #endif
2904  }
void get_bin_vertices(const unsigned &i_bin, Vector< Vector< double >> &bin_vertex)
Definition: sample_point_container.cc:2912
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152

References BinArray::Dimensions_of_bin_array, get_bin_vertices(), i, int(), j, SamplePointContainer::Min_and_max_coordinates, Global_Physical_Variables::multiplier(), BinArray::ndim_zeta(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Eigen::bfloat16_impl::pow(), and Eigen::zeta().

◆ get_bin() [2/2]

void NonRefineableBinArray::get_bin ( const Vector< double > &  zeta,
int bin_number,
Vector< std::pair< FiniteElement *, Vector< double >>> &  sample_point_pairs 
)

Get the number of the bin containing the specified coordinate; also return the contents of that bin. Bin number is negative if the coordinate is outside the bin structure.

◆ get_bin_vertices()

void NonRefineableBinArray::get_bin_vertices ( const unsigned i_bin,
Vector< Vector< double >> &  bin_vertex 
)

Get vector of vectors containing the coordinates of the vertices of the i_bin-th bin: bin_vertex[j][i] contains the i-th coordinate of the j-th vertex.

2914  {
2915  // Spatial dimension of bin
2916  const unsigned n_lagrangian = this->ndim_zeta();
2917 
2918  // How many vertices do we have?
2919  unsigned n_vertices = 1;
2920  for (unsigned i = 0; i < n_lagrangian; i++)
2921  {
2922  n_vertices *= 2;
2923  }
2924  bin_vertex.resize(n_vertices);
2925 
2926  // Vectors for min [0] and max [1] coordinates of the bin in each
2927  // coordinate direction
2928  Vector<Vector<double>> zeta_vertex_bin(2);
2929  zeta_vertex_bin[0].resize(n_lagrangian);
2930  zeta_vertex_bin[1].resize(n_lagrangian);
2931 
2932  Vector<double> dzeta;
2933  unsigned count = 0;
2934  Vector<unsigned> i_1d;
2935 
2936  // Deal with different spatial dimensions separately
2937  switch (n_lagrangian)
2938  {
2939  case 1:
2940 
2941  // Assign vertex coordinates of the bin directly
2942  dzeta.resize(1);
2943  dzeta[0] = (Min_and_max_coordinates[0].second -
2944  Min_and_max_coordinates[0].first) /
2945  double(Dimensions_of_bin_array[0]);
2946  bin_vertex[0].resize(1);
2947  bin_vertex[0][0] =
2948  Min_and_max_coordinates[0].first + double(i_bin) * dzeta[0];
2949  bin_vertex[1].resize(1);
2950  bin_vertex[1][0] =
2951  Min_and_max_coordinates[0].first + double(i_bin + 1) * dzeta[0];
2952 
2953  break;
2954 
2955  case 2:
2956 
2957  dzeta.resize(2);
2958  dzeta[0] = (Min_and_max_coordinates[0].second -
2959  Min_and_max_coordinates[0].first) /
2960  double(Dimensions_of_bin_array[0]);
2961  dzeta[1] = (Min_and_max_coordinates[1].second -
2962  Min_and_max_coordinates[1].first) /
2963  double(Dimensions_of_bin_array[1]);
2964 
2965  i_1d.resize(2);
2966  i_1d[0] = i_bin % Dimensions_of_bin_array[0];
2967  i_1d[1] = (i_bin - i_1d[0]) / Dimensions_of_bin_array[0];
2968 
2969  // Max/min coordinates of the bin
2970  for (unsigned i = 0; i < n_lagrangian; i++)
2971  {
2972  zeta_vertex_bin[0][i] =
2973  Min_and_max_coordinates[i].first + double(i_1d[i]) * dzeta[i];
2974  zeta_vertex_bin[1][i] =
2975  Min_and_max_coordinates[i].first + double(i_1d[i] + 1) * dzeta[i];
2976  }
2977 
2978  // Build 4 vertex coordinates
2979  count = 0;
2980  for (unsigned i_min_max = 0; i_min_max < 2; i_min_max++)
2981  {
2982  for (unsigned j_min_max = 0; j_min_max < 2; j_min_max++)
2983  {
2984  bin_vertex[count].resize(2);
2985  bin_vertex[count][0] = zeta_vertex_bin[i_min_max][0];
2986  bin_vertex[count][1] = zeta_vertex_bin[j_min_max][1];
2987  count++;
2988  }
2989  }
2990 
2991  break;
2992 
2993  case 3:
2994 
2995  dzeta.resize(3);
2996  dzeta[0] = (Min_and_max_coordinates[0].second -
2997  Min_and_max_coordinates[0].first) /
2998  double(Dimensions_of_bin_array[0]);
2999  dzeta[1] = (Min_and_max_coordinates[1].second -
3000  Min_and_max_coordinates[1].first) /
3001  double(Dimensions_of_bin_array[1]);
3002  dzeta[2] = (Min_and_max_coordinates[2].second -
3003  Min_and_max_coordinates[2].first) /
3004  double(Dimensions_of_bin_array[2]);
3005 
3006  i_1d.resize(3);
3007  i_1d[0] = i_bin % Dimensions_of_bin_array[0];
3008  i_1d[1] = ((i_bin - i_1d[0]) / Dimensions_of_bin_array[0]) %
3010  i_1d[2] = (i_bin - (i_1d[1] * Dimensions_of_bin_array[0] + i_1d[0])) /
3012 
3013  // Max/min coordinates of the bin
3014  for (unsigned i = 0; i < n_lagrangian; i++)
3015  {
3016  zeta_vertex_bin[0][i] =
3017  Min_and_max_coordinates[i].first + double(i_1d[i]) * dzeta[i];
3018  zeta_vertex_bin[1][i] =
3019  Min_and_max_coordinates[i].first + double(i_1d[i] + 1) * dzeta[i];
3020  }
3021 
3022  // Build 8 vertex coordinates
3023  count = 0;
3024  for (unsigned i_min_max = 0; i_min_max < 2; i_min_max++)
3025  {
3026  for (unsigned j_min_max = 0; j_min_max < 2; j_min_max++)
3027  {
3028  for (unsigned k_min_max = 0; k_min_max < 2; k_min_max++)
3029  {
3030  bin_vertex[count].resize(3);
3031  bin_vertex[count][0] = zeta_vertex_bin[i_min_max][0];
3032  bin_vertex[count][1] = zeta_vertex_bin[j_min_max][1];
3033  bin_vertex[count][2] = zeta_vertex_bin[k_min_max][2];
3034  count++;
3035  }
3036  }
3037  }
3038 
3039  break;
3040 
3041  default:
3042 
3043  std::ostringstream error_message;
3044  error_message << "Can't deal with bins in dimension " << n_lagrangian
3045  << "\n";
3046  throw OomphLibError(error_message.str(),
3049  }
3050  }

References BinArray::Dimensions_of_bin_array, i, SamplePointContainer::Min_and_max_coordinates, BinArray::ndim_zeta(), OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

Referenced by get_bin(), min_distance(), and output_bin_vertices().

◆ get_fill_stats()

void NonRefineableBinArray::get_fill_stats ( unsigned n_bin,
unsigned max_n_entry,
unsigned min_n_entry,
unsigned tot_n_entry,
unsigned n_empty 
) const

Provide some stats on the fill level of the associated bin.

2634  {
2635  // Total number of bins
2636  n_bin = nbin();
2637  n_empty = n_bin - Bin_object_coord_pairs.nnz();
2638 
2639  // Get pointer to map-based representation
2640  const std::map<unsigned, Vector<std::pair<FiniteElement*, Vector<double>>>>*
2641  map_pt = Bin_object_coord_pairs.map_pt();
2642 
2643  // Initialise
2644  max_n_entry = 0;
2645  min_n_entry = UINT_MAX;
2646  tot_n_entry = 0;
2647 
2648  // Do stats
2649  typedef std::map<
2650  unsigned,
2651  Vector<std::pair<FiniteElement*, Vector<double>>>>::const_iterator IT;
2652  for (IT it = map_pt->begin(); it != map_pt->end(); it++)
2653  {
2654  unsigned nentry = (*it).second.size();
2655  if (nentry > max_n_entry) max_n_entry = nentry;
2656  if (nentry < min_n_entry) min_n_entry = nentry;
2657  tot_n_entry += nentry;
2658  }
2659  }

References Bin_object_coord_pairs, and nbin().

◆ locate_zeta()

void NonRefineableBinArray::locate_zeta ( const Vector< double > &  zeta,
GeomObject *&  sub_geom_object_pt,
Vector< double > &  s 
)
virtual

Find sub-GeomObject (finite element) and the local coordinate s within it that contains point with global coordinate zeta. sub_geom_object_pt=0 if point can't be found.

Find the sub geometric object and local coordinate therein that corresponds to the intrinsic coordinate zeta. If sub_geom_object_pt=0 on return from this function, none of the constituent sub-objects contain the required coordinate.

Implements SamplePointContainer.

3091  {
3092  // Reset counter for number of sample points visited only if we're
3093  // starting from the beginning
3094  if (current_min_spiral_level() == 0)
3095  {
3097  0;
3098  }
3099 
3100  // Initialise return to null -- if it's still null when we're
3101  // leaving we've failed!
3102  sub_geom_object_pt = 0;
3103 
3104  // Get the lagrangian dimension
3105  const unsigned n_lagrangian = this->ndim_zeta();
3106 
3107  // Does the zeta coordinate lie within the current bin structure?
3108  // Skip this test if we want to always fail because that's usually
3109  // done to trace out the spiral path
3111  {
3112  // Loop over the lagrangian dimension
3113  for (unsigned i = 0; i < n_lagrangian; i++)
3114  {
3115  // If the i-th coordinate is less than the minimum
3116  if (zeta[i] < Min_and_max_coordinates[i].first)
3117  {
3118  return;
3119  }
3120  // Otherwise coordinate may be bigger than the maximum
3121  else if (zeta[i] > Min_and_max_coordinates[i].second)
3122  {
3123  return;
3124  }
3125  }
3126  }
3127 
3128  // Use the min and max coords of the bin structure, to find
3129  // the bin structure containing the current zeta cooordinate
3130  unsigned bin_number = 0;
3131 
3132  // Offset for rows/matrices in higher dimensions
3133  unsigned multiplier = 1;
3134 
3135  // Loop over the dimension
3136  for (unsigned i = 0; i < n_lagrangian; i++)
3137  {
3138  // Find the bin number of the current coordinate
3139  unsigned bin_number_i =
3141  ((zeta[i] - Min_and_max_coordinates[i].first) /
3142  (Min_and_max_coordinates[i].second -
3143  Min_and_max_coordinates[i].first)));
3144 
3145  // Buffer the case when we are exactly on the edge
3146  if (bin_number_i == Dimensions_of_bin_array[i])
3147  {
3148  bin_number_i -= 1;
3149  }
3150 
3151  // Now add to the bin number using the multiplier
3152  bin_number += multiplier * bin_number_i;
3153 
3154  // Increase the current row/matrix multiplier for the next loop
3156  }
3157 
3158  // Loop over spirals that are to be visited in one go
3159  Vector<unsigned> neighbour_bin;
3160  unsigned min_level = current_min_spiral_level();
3161  unsigned max_level = current_max_spiral_level();
3162  for (unsigned i_level = min_level; i_level <= max_level; i_level++)
3163  {
3164  // Call helper function to find the neighbouring bins at this
3165  // level
3166  get_neighbouring_bins_helper(bin_number, i_level, neighbour_bin);
3167 
3168  // Total number of bins to be visited
3169  unsigned n_nbr_bin = neighbour_bin.size();
3170 
3171  // // keep around and add "false" as last argument to previous call
3172  // // to get_neighbouring_bins_helper(...) for annotation below to make
3173  // sense
3174  // {
3175  // Vector<unsigned> old_neighbour_bin;
3176  // get_neighbouring_bins_helper(bin_number,
3177  // i_level,
3178  // old_neighbour_bin,
3179  // true); // true=use old version!
3180  // unsigned nbin_new = neighbour_bin.size();
3181  // unsigned nbin_old = old_neighbour_bin.size();
3182  // unsigned n=std::min(nbin_new,nbin_old);
3183  // std::sort(old_neighbour_bin.begin(),
3184  // old_neighbour_bin.end());
3185  // std::sort(neighbour_bin.begin(),
3186  // neighbour_bin.end());
3187  // oomph_info << "# of neighbouring bins: "
3188  // << nbin_new << " " << nbin_old;
3189  // if (nbin_new!=nbin_old)
3190  // {
3191  // oomph_info << " DIFFERENT!";
3192  // }
3193  // oomph_info << std::endl;
3194  // for (unsigned i=0;i<n;i++)
3195  // {
3196  // oomph_info << neighbour_bin[i] << " "
3197  // << old_neighbour_bin[i] << " ";
3198  // if (neighbour_bin[i]!=
3199  // old_neighbour_bin[i])
3200  // {
3201  // oomph_info << "DIFFFFERENT";
3202  // }
3203  // oomph_info << std::endl;
3204  // }
3205  // if (nbin_new>nbin_old)
3206  // {
3207  // for (unsigned i=n;i<nbin_new;i++)
3208  // {
3209  // oomph_info << "NNEW:" << neighbour_bin[i]
3210  // << std::endl;
3211  // }
3212  // }
3213  // if (nbin_old>nbin_new)
3214  // {
3215  // for (unsigned i=n;i<nbin_old;i++)
3216  // {
3217  // oomph_info << "OOLD:" << old_neighbour_bin[i]
3218  // << std::endl;
3219  // }
3220  // }
3221  // }
3222 
3223 
3224  // Set bool for finding zeta
3225  bool found_zeta = false;
3226  for (unsigned i_nbr = 0; i_nbr < n_nbr_bin; i_nbr++)
3227  {
3228  // Only search if bin is within the max. radius but min_distance
3229  // is expensive...
3230  bool do_it = true;
3231  if (Max_search_radius < DBL_MAX)
3232  {
3233  if (min_distance(neighbour_bin[i_nbr], zeta) > Max_search_radius)
3234  {
3235  do_it = false;
3236  }
3237  }
3238  if (do_it)
3239  {
3240  // Get the number of element-sample point pairs in this bin
3241  unsigned n_sample =
3242  Bin_object_coord_pairs[neighbour_bin[i_nbr]].size();
3243 
3244  // Don't do anything if this bin has no sample points
3245  if (n_sample > 0)
3246  {
3247  for (unsigned i_sam = 0; i_sam < n_sample; i_sam++)
3248  {
3249  // Get the element
3250  FiniteElement* el_pt =
3251  Bin_object_coord_pairs[neighbour_bin[i_nbr]][i_sam].first;
3252 
3253  // Get the local coordinate
3254  s = Bin_object_coord_pairs[neighbour_bin[i_nbr]][i_sam].second;
3255 
3256  // History of sample points visited
3258  {
3259  unsigned cached_dim_zeta = this->ndim_zeta();
3260  Vector<double> zeta_sample(cached_dim_zeta);
3262  {
3263  el_pt->interpolated_x(s, zeta_sample);
3264  }
3265  else
3266  {
3267  el_pt->interpolated_zeta(s, zeta_sample);
3268  }
3269  double dist = 0.0;
3270  for (unsigned ii = 0; ii < cached_dim_zeta; ii++)
3271  {
3272  BinArray::Visited_sample_points_file << zeta_sample[ii]
3273  << " ";
3274  dist +=
3275  (zeta[ii] - zeta_sample[ii]) * (zeta[ii] - zeta_sample[ii]);
3276  }
3279  << " " << sqrt(dist) << std::endl;
3280  }
3281 
3282  // Use this coordinate as the initial guess
3283  bool use_coordinate_as_initial_guess = true;
3284 
3285  // Attempt to find zeta within a sub-object
3286  el_pt->locate_zeta(
3287  zeta, sub_geom_object_pt, s, use_coordinate_as_initial_guess);
3288 
3289 
3291 
3292  // Always fail? (Used for debugging, e.g. to trace out
3293  // spiral path)
3295  {
3296  sub_geom_object_pt = 0;
3297  }
3298 
3299 
3300 #ifdef OOMPH_HAS_MPI
3301  // Ignore halos?
3302  if (Ignore_halo_elements_during_locate_zeta_search)
3303  {
3304  // Dynamic cast the result to a FiniteElement
3305  FiniteElement* test_el_pt =
3306  dynamic_cast<FiniteElement*>(sub_geom_object_pt);
3307  if (test_el_pt != 0)
3308  {
3309  // We only want to exit if this is a non-halo element
3310  if (test_el_pt->is_halo())
3311  {
3312  sub_geom_object_pt = 0;
3313  }
3314  }
3315  }
3316 #endif
3317 
3318  // If the FiniteElement is non-halo and has been located, exit
3319  if (sub_geom_object_pt != 0)
3320  {
3321  found_zeta = true;
3322  break;
3323  }
3324  } // end loop over sample points
3325  }
3326 
3327 
3328  if (found_zeta)
3329  {
3330  return; // break;
3331  }
3332 
3333  } // end of don't search if outside search radius
3334  } // end loop over bins at this level
3335  } // End of loop over levels
3336  }
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
unsigned & current_max_spiral_level()
Access function to current max. spiral level.
Definition: sample_point_container.h:891
unsigned & current_min_spiral_level()
Access function to current min. spiral level.
Definition: sample_point_container.h:885
static bool Always_fail_elemental_locate_zeta
Boolean flag to make to make locate zeta fail.
Definition: sample_point_container.h:339
bool use_eulerian_coordinates_during_setup() const
Definition: sample_point_container.h:308
unsigned Total_number_of_sample_points_visited_during_locate_zeta_from_top_level
Definition: sample_point_container.h:382
double Max_search_radius
Definition: sample_point_container.h:389
static std::ofstream Visited_sample_points_file
File to record sequence of visited sample points in.
Definition: sample_point_container.h:335
virtual unsigned & total_number_of_sample_points_visited_during_locate_zeta_from_top_level()
Definition: sample_point_container.h:261

References SamplePointContainer::Always_fail_elemental_locate_zeta, Bin_object_coord_pairs, current_max_spiral_level(), current_min_spiral_level(), BinArray::Dimensions_of_bin_array, BinArray::get_neighbouring_bins_helper(), i, int(), SamplePointContainer::Max_search_radius, SamplePointContainer::Min_and_max_coordinates, min_distance(), Global_Physical_Variables::multiplier(), BinArray::ndim_zeta(), s, sqrt(), SamplePointContainer::total_number_of_sample_points_visited_during_locate_zeta_from_top_level(), SamplePointContainer::Total_number_of_sample_points_visited_during_locate_zeta_from_top_level, SamplePointContainer::use_eulerian_coordinates_during_setup(), SamplePointContainer::Visited_sample_points_file, and Eigen::zeta().

◆ max_spiral_level()

unsigned& NonRefineableBinArray::max_spiral_level ( )
inline

Access function to max. spiral level during straight locate_zeta search (for efficiency; similar to max_search_radius())

880  {
881  return Max_spiral_level;
882  }

References Max_spiral_level.

◆ min_distance()

double NonRefineableBinArray::min_distance ( const unsigned i_bin,
const Vector< double > &  zeta 
)

Compute the minimum distance of any vertex in the specified bin from the specified Lagrangian coordinate zeta

Compute the minimum distance of any vertex in the specified bin from the specified Lagrangian coordinate zeta.

3059  {
3060  // Spatial dimension of bin
3061  const unsigned n_lagrangian = this->ndim_zeta();
3062 
3063  // Get bin vertices
3064  Vector<Vector<double>> bin_vertex;
3065  get_bin_vertices(i_bin, bin_vertex);
3066  double min_dist = DBL_MAX;
3067  unsigned nvertex = bin_vertex.size();
3068  for (unsigned v = 0; v < nvertex; v++)
3069  {
3070  double dist = 0.0;
3071  for (unsigned i = 0; i < n_lagrangian; i++)
3072  {
3073  dist += pow(bin_vertex[v][i] - zeta[i], 2);
3074  }
3075  dist = sqrt(dist);
3076  if (dist < min_dist) min_dist = dist;
3077  }
3078  return min_dist;
3079  }
Array< int, Dynamic, 1 > v
Definition: Array_initializer_list_vector_cxx11.cpp:1

References get_bin_vertices(), i, BinArray::ndim_zeta(), Eigen::bfloat16_impl::pow(), sqrt(), v, and Eigen::zeta().

Referenced by fill_bin_by_diffusion(), and locate_zeta().

◆ n_spiral_chunk() [1/2]

unsigned& NonRefineableBinArray::n_spiral_chunk ( )
inline

Number of spirals to be searched in one go.

873  {
874  return Nspiral_chunk;
875  }

References Nspiral_chunk.

◆ n_spiral_chunk() [2/2]

unsigned NonRefineableBinArray::n_spiral_chunk ( ) const
inline

Number of spirals to be searched in one go const version.

867  {
868  return Nspiral_chunk;
869  }

References Nspiral_chunk.

Referenced by oomph::Multi_domain_functions::aux_setup_multi_domain_interaction(), and check_locate_zeta().

◆ nbin()

unsigned NonRefineableBinArray::nbin ( ) const
inlinevirtual

Total number of bins (empty or not)

Implements BinArray.

846  {
847  const unsigned n_lagrangian = ndim_zeta();
848  unsigned ntotalbin = Dimensions_of_bin_array[0];
849  for (unsigned i = 1; i < n_lagrangian; i++)
850  {
851  ntotalbin *= Dimensions_of_bin_array[i];
852  }
853  return ntotalbin;
854  }

References BinArray::Dimensions_of_bin_array, i, and BinArray::ndim_zeta().

Referenced by fill_bin_array(), fill_bin_by_diffusion(), get_fill_stats(), and output_bin_vertices().

◆ operator=()

void NonRefineableBinArray::operator= ( const NonRefineableBinArray )
delete

Broken assignment operator.

◆ output_bin_vertices()

void NonRefineableBinArray::output_bin_vertices ( std::ofstream &  outfile)
virtual

Output bin vertices (allowing display of bins as zones).

Implements BinArray.

2358  {
2359  // Store the lagrangian dimension
2360  const unsigned n_lagrangian = this->ndim_zeta();
2361 
2362  unsigned nbin = Dimensions_of_bin_array[0];
2363  if (n_lagrangian > 1) nbin *= Dimensions_of_bin_array[1];
2364  if (n_lagrangian > 2) nbin *= Dimensions_of_bin_array[2];
2365 
2366  for (unsigned i_bin = 0; i_bin < nbin; i_bin++)
2367  {
2368  // Get bin vertices
2369  Vector<Vector<double>> bin_vertex;
2370  get_bin_vertices(i_bin, bin_vertex);
2371  switch (n_lagrangian)
2372  {
2373  case 1:
2374  outfile << "ZONE I=2\n";
2375  break;
2376 
2377  case 2:
2378  outfile << "ZONE I=2, J=2\n";
2379  break;
2380 
2381  case 3:
2382  outfile << "ZONE I=2, J=2, K=2\n";
2383  break;
2384  }
2385 
2386  unsigned nvertex = bin_vertex.size();
2387  for (unsigned i = 0; i < nvertex; i++)
2388  {
2389  for (unsigned j = 0; j < n_lagrangian; j++)
2390  {
2391  outfile << bin_vertex[i][j] << " ";
2392  }
2393  outfile << std::endl;
2394  }
2395  }
2396  }

References BinArray::Dimensions_of_bin_array, get_bin_vertices(), i, j, nbin(), and BinArray::ndim_zeta().

◆ output_bins() [1/2]

void NonRefineableBinArray::output_bins ( std::ofstream &  outfile)
virtual

Output bins.

Implements BinArray.

2309  {
2310  // Spatial dimension of bin
2311  const unsigned n_lagrangian = this->ndim_zeta();
2312 
2313  unsigned nbin_x = Dimensions_of_bin_array[0];
2314  unsigned nbin_y = 1;
2315  if (n_lagrangian > 1) nbin_y = Dimensions_of_bin_array[1];
2316  unsigned nbin_z = 1;
2317  if (n_lagrangian > 2) nbin_z = Dimensions_of_bin_array[2];
2318 
2319  unsigned b = 0;
2320  for (unsigned iz = 0; iz < nbin_z; iz++)
2321  {
2322  for (unsigned iy = 0; iy < nbin_y; iy++)
2323  {
2324  for (unsigned ix = 0; ix < nbin_x; ix++)
2325  {
2326  unsigned nentry = Bin_object_coord_pairs[b].size();
2327  for (unsigned e = 0; e < nentry; e++)
2328  {
2329  FiniteElement* el_pt = Bin_object_coord_pairs[b][e].first;
2330  Vector<double> s(Bin_object_coord_pairs[b][e].second);
2331  Vector<double> zeta(n_lagrangian);
2333  {
2334  el_pt->interpolated_x(s, zeta);
2335  }
2336  else
2337  {
2338  el_pt->interpolated_zeta(s, zeta);
2339  }
2340  for (unsigned i = 0; i < n_lagrangian; i++)
2341  {
2342  outfile << zeta[i] << " ";
2343  }
2344  outfile << ix << " " << iy << " " << iz << " " << b << " "
2345  << std::endl;
2346  }
2347  b++;
2348  }
2349  }
2350  }
2351  }
Scalar * b
Definition: benchVecAdd.cpp:17

References b, Bin_object_coord_pairs, BinArray::Dimensions_of_bin_array, e(), i, BinArray::ndim_zeta(), s, SamplePointContainer::Use_eulerian_coordinates_during_setup, and Eigen::zeta().

Referenced by output_bins().

◆ output_bins() [2/2]

void NonRefineableBinArray::output_bins ( std::string &  filename)
inline

Output bins.

956  {
957  std::ofstream outfile;
958  outfile.open(filename.c_str());
959  output_bins(outfile);
960  outfile.close();
961  }
void output_bins(std::ofstream &outfile)
Output bins.
Definition: sample_point_container.cc:2308
string filename
Definition: MergeRestartFiles.py:39

References MergeRestartFiles::filename, and output_bins().

◆ total_number_of_sample_points_computed_recursively()

unsigned NonRefineableBinArray::total_number_of_sample_points_computed_recursively ( ) const
virtual

Compute total number of sample points recursively.

Implements SamplePointContainer.

2285  {
2286  // Get pointer to map-based representation
2287  const std::map<unsigned, Vector<std::pair<FiniteElement*, Vector<double>>>>*
2288  map_pt = Bin_object_coord_pairs.map_pt();
2289 
2290  // Initialise
2291  unsigned count = 0;
2292 
2293  // loop...
2294  typedef std::map<
2295  unsigned,
2296  Vector<std::pair<FiniteElement*, Vector<double>>>>::const_iterator IT;
2297  for (IT it = map_pt->begin(); it != map_pt->end(); it++)
2298  {
2299  count += (*it).second.size();
2300  }
2301  return count;
2302  }

References Bin_object_coord_pairs.

Referenced by NonRefineableBinArray().

Member Data Documentation

◆ Already_warned_about_large_number_of_bin_cells

bool NonRefineableBinArray::Already_warned_about_large_number_of_bin_cells
static
Initial value:
=
false

Boolean flag to make sure that warning about large number of bin cells only gets triggered once.

Referenced by fill_bin_array().

◆ Already_warned_about_small_number_of_bin_cells

bool NonRefineableBinArray::Already_warned_about_small_number_of_bin_cells
static
Initial value:
=
false

Boolean flag to make sure that warning about small number of bin cells only gets triggered once.

Referenced by fill_bin_array().

◆ Bin_object_coord_pairs

SparseVector<Vector<std::pair<FiniteElement*, Vector<double> > > > NonRefineableBinArray::Bin_object_coord_pairs
private

◆ Current_max_spiral_level

unsigned NonRefineableBinArray::Current_max_spiral_level
private

Current max. spiralling level.

Referenced by current_max_spiral_level(), and NonRefineableBinArray().

◆ Current_min_spiral_level

unsigned NonRefineableBinArray::Current_min_spiral_level
private

Current min. spiralling level.

Referenced by current_min_spiral_level(), and NonRefineableBinArray().

◆ Default_n_bin_1d

unsigned NonRefineableBinArray::Default_n_bin_1d = 100
static

Default number of bins (in each coordinate direction)

Default number of bins (in each coordinate direction). (Note: don't move this into a common base class because each derived class has its own value; nonrefineable bin wants a much larger value than the refineable one!)

Referenced by NonRefineableBinArray(), and UnstructuredFSIProblem< FLUID_ELEMENT, SOLID_ELEMENT >::UnstructuredFSIProblem().

◆ Max_spiral_level

unsigned NonRefineableBinArray::Max_spiral_level
private

Max. spiralling level (for efficiency; effect similar to max_search_radius)

Referenced by max_spiral_level(), and NonRefineableBinArray().

◆ Nspiral_chunk

unsigned NonRefineableBinArray::Nspiral_chunk
private

Number of spirals to be searched in one go.

Referenced by n_spiral_chunk(), and NonRefineableBinArray().

◆ Suppress_warning_about_large_total_number_of_bins

bool NonRefineableBinArray::Suppress_warning_about_large_total_number_of_bins
static
Initial value:
=
false

Boolean to supppress warnings about large number of bins.

Referenced by fill_bin_array().

◆ Suppress_warning_about_small_number_of_bins

bool NonRefineableBinArray::Suppress_warning_about_small_number_of_bins
static
Initial value:
=
false

Boolean to supppress warnings about small number of bins.

Referenced by fill_bin_array().

◆ Threshold_for_elements_per_bin_warning

unsigned NonRefineableBinArray::Threshold_for_elements_per_bin_warning = 100
static

Fraction of elements/bin that triggers warning. Too many elements per bin can lead to very slow computations

Referenced by fill_bin_array().

◆ Threshold_for_total_bin_cell_number_warning

unsigned long NonRefineableBinArray::Threshold_for_total_bin_cell_number_warning
static
Initial value:
=
50000000

Total number of bins above which warning is issued. (Default assignment of 100^DIM bins per MeshAsGeomObject can be a killer if there are huge numbers of sub-meshes (e.g. in unstructured FSI).

Referenced by fill_bin_array().

◆ Total_nbin_cells_counter

unsigned long NonRefineableBinArray::Total_nbin_cells_counter = 0
static

Counter for overall number of bins allocated – used to issue warning if this exceeds a threshhold. (Default assignment of 100^DIM bins per MeshAsGeomObject can be a killer if there are huge numbers of sub-meshes (e.g. in unstructured FSI).

Referenced by fill_bin_array(), and flush_bins_of_objects().


The documentation for this class was generated from the following files: