oomph::LineVisualiser Class Reference

#include <line_visualiser.h>

Public Member Functions

 LineVisualiser (Mesh *mesh_pt, const Vector< Vector< double >> &coord_vec, const double &max_search_radius=DBL_MAX)
 
 LineVisualiser (Mesh *mesh_pt, const std::string file_name, const double &scale=1.0)
 
 LineVisualiser (Mesh *mesh_pt, const double &max_search_radius, const std::string file_name, const double &scale=1.0)
 
void output (std::ostream &outfile)
 
void get_output_data (Vector< Vector< double >> &data)
 
void update_plot_points_coordinates (Vector< Vector< double >> &coord_vec)
 

Private Member Functions

void setup_from_file (Mesh *mesh_pt, const std::string file_name, const double &scale)
 Helper function to setup from file. More...
 
void setup (Mesh *mesh_pt, const Vector< Vector< double >> &coord_vec)
 Helper function to setup the output structures. More...
 
void get_local_plot_points_coordinates (Vector< Vector< double >> &data)
 

Private Attributes

double Max_search_radius
 
OomphCommunicatorComm_pt
 
Vector< std::pair< FiniteElement *, Vector< double > > > Plot_point
 
unsigned Nplot_points
 Number of plot points. More...
 

Detailed Description

Class to aid visualisation of the values on a set of points. NOTE: in a distributed problem, output is only done on processor 0.

Constructor & Destructor Documentation

◆ LineVisualiser() [1/3]

oomph::LineVisualiser::LineVisualiser ( Mesh mesh_pt,
const Vector< Vector< double >> &  coord_vec,
const double max_search_radius = DBL_MAX 
)
inline

Constructor: Pass pointer to mesh and coordinates of desired plot points: coord_vec[j][i] is the i-th coordinate of the j-th plot point. Optional final parameter specifies the maximum search radius in bin when locating the plot points. Defaults to DBL_MAX and will therefore keep searching through the entire bin structure if a point cannot be found. It's worth limiting this to the order of the size of a typical element in the mesh in parallel computations with fine meshes, otherwise the setup can take forever.

63  : Max_search_radius(max_search_radius),
64  Comm_pt(mesh_pt->communicator_pt())
65  {
66  // Do the actual work
67  setup(mesh_pt, coord_vec);
68  }
OomphCommunicator * Comm_pt
Definition: line_visualiser.h:600
void setup(Mesh *mesh_pt, const Vector< Vector< double >> &coord_vec)
Helper function to setup the output structures.
Definition: line_visualiser.h:668
double Max_search_radius
Definition: line_visualiser.h:596

References setup().

◆ LineVisualiser() [2/3]

oomph::LineVisualiser::LineVisualiser ( Mesh mesh_pt,
const std::string  file_name,
const double scale = 1.0 
)
inline

Constructor reading centerline file

  • Open "file_name" and extract 3 first doubles of each line
  • Skip lines which does not begin with a number. Scaling factor allows points defined in input file to be scaled.
78  : Max_search_radius(DBL_MAX), Comm_pt(mesh_pt->communicator_pt())
79  {
80  setup_from_file(mesh_pt, file_name, scale);
81  }
void setup_from_file(Mesh *mesh_pt, const std::string file_name, const double &scale)
Helper function to setup from file.
Definition: line_visualiser.h:603
string file_name
Definition: Particles2023AnalysisHung.py:321

References Particles2023AnalysisHung::file_name, and setup_from_file().

◆ LineVisualiser() [3/3]

oomph::LineVisualiser::LineVisualiser ( Mesh mesh_pt,
const double max_search_radius,
const std::string  file_name,
const double scale = 1.0 
)
inline

Constructor reading centerline file

  • Open "file_name" and extract 3 first doubles of each line
  • Skip lines which does not begin with a number. Scaling factor allows points defined in input file to be scaled. Second parameter specifies the maximum search radius in bin when locating the plot points. It's worth setting this to the order of the size of a typical element in the mesh in parallel computations with fine meshes, otherwise the setup can take forever.
97  : Max_search_radius(max_search_radius),
98  Comm_pt(mesh_pt->communicator_pt())
99  {
100  setup_from_file(mesh_pt, file_name, scale);
101  }

References Particles2023AnalysisHung::file_name, and setup_from_file().

Member Function Documentation

◆ get_local_plot_points_coordinates()

void oomph::LineVisualiser::get_local_plot_points_coordinates ( Vector< Vector< double >> &  data)
inlineprivate
802  {
803  data.resize(Nplot_points);
804  for (unsigned i = 0; i < Nplot_points; i++)
805  {
806  if (Plot_point[i].first != NULL)
807  {
808  unsigned dim = Plot_point[i].second.size();
809 
810  data[i].resize(dim);
811 
812  for (unsigned j = 0; j < dim; j++)
813  {
814  data[i][j] =
815  Plot_point[i].first->interpolated_x(Plot_point[i].second, j);
816  }
817  }
818  }
819  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
int data[]
Definition: Map_placement_new.cpp:1
Vector< std::pair< FiniteElement *, Vector< double > > > Plot_point
Definition: line_visualiser.h:824
unsigned Nplot_points
Number of plot points.
Definition: line_visualiser.h:827
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References data, i, j, Nplot_points, and Plot_point.

Referenced by update_plot_points_coordinates().

◆ get_output_data()

void oomph::LineVisualiser::get_output_data ( Vector< Vector< double >> &  data)
inline

Output data function: store data associated with each plot point in data array

135  {
136  // Resize output data array
137  data.resize(Nplot_points);
138 
139  // Check if mesh is distributed and a communication pointer
140  // exists.
141  if (Comm_pt != 0)
142  {
143  int nproc = Comm_pt->nproc();
144 
145  if (nproc > 1)
146  {
147 #ifdef OOMPH_HAS_MPI
148 
149  // Declaration of MPI variables
150  MPI_Status stat;
151  int tag = 0;
152  int my_rank = Comm_pt->my_rank();
153 
154 
155  // Buffer
156  unsigned buff_size;
157 
158  // Create array which contains data found in every process
159  Vector<Vector<double>> vec(Nplot_points);
160 
161  // Loop over the points to fill in vec
162  for (unsigned i = 0; i < Nplot_points; i++)
163  {
164  // Check if the point was found in the mesh
165  if (Plot_point[i].first != NULL) // success
166  {
167  // Check if the point is halo
168  if (!((*Plot_point[i].first).is_halo()))
169  {
170  // Get the line of output data from the element
171  // (specified by .first), at its local coordinate
172  // (specified by .second)
173  Plot_point[i].first->point_output_data(Plot_point[i].second,
174  vec[i]);
175  }
176  }
177  }
178 
179 
180  // Analyse which plot points have been found
181  // locally and concatenate the data:
182 
183  // This contains the flat-packed doubles to be sent
184  // for all located plot points
185  Vector<double> local_values;
186 
187  // Number of values to be sent for each plot point
188  // (almost certainly the same for all plot points, but...)
189  // size_values[i] gives the number of doubles to be
190  // sent for plot point i.
191  Vector<unsigned> size_values;
192 
193  // Each processor indicates if it has found a given plot point.
194  // Once this is gathered on the root processor we know
195  // exactly which data we'll receive from where.
196  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points, 0);
197 
198  // Loop over the plot points
199  for (unsigned i = 0; i < Nplot_points; i++)
200  {
201  unsigned ndata = vec[i].size();
202  if (ndata != 0)
203  {
204  // Store the number of fields
205  size_values.push_back(ndata);
206 
207  // Update found vector
208  tmp_proc_point_found_plus_one[i] = my_rank + 1;
209 
210  // Store values
211  for (unsigned j = 0; j < ndata; j++)
212  {
213  local_values.push_back(vec[i][j]);
214  }
215  }
216  }
217 
218  // Gather information on root
219 
220  // Find out who's found the points
221  Vector<unsigned> proc_point_found_plus_one(Nplot_points, 0);
222  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
223  &proc_point_found_plus_one[0],
224  Nplot_points,
225  MPI_UNSIGNED,
226  MPI_MAX,
227  0,
228  Comm_pt->mpi_comm());
229 
230 
231  // Main process write data
232  if (my_rank == 0)
233  {
234  // Collect all the data
235  Vector<Vector<double>> received_data(nproc - 1);
236  Vector<Vector<unsigned>> received_size(nproc - 1);
237  Vector<unsigned> counter_d(nproc - 1, 0);
238  Vector<unsigned> counter_s(nproc - 1, 0);
239 
240  // Loop over processors that send their points
241  for (int i = 1; i < nproc; i++)
242  {
243  // Receive sizes of data
244  MPI_Recv(&buff_size,
245  1,
246  MPI_UNSIGNED,
247  i,
248  tag,
249  Comm_pt->mpi_comm(),
250  &stat);
251  received_size[i - 1].resize(std::max(unsigned(1), buff_size));
252  MPI_Recv(&received_size[i - 1][0],
253  buff_size,
254  MPI_UNSIGNED,
255  i,
256  tag,
257  Comm_pt->mpi_comm(),
258  &stat);
259 
260  // Receive actual data
261  MPI_Recv(&buff_size,
262  1,
263  MPI_UNSIGNED,
264  i,
265  tag,
266  Comm_pt->mpi_comm(),
267  &stat);
268  received_data[i - 1].resize(std::max(unsigned(1), buff_size));
269  MPI_Recv(&received_data[i - 1][0],
270  buff_size,
271  MPI_DOUBLE,
272  i,
273  tag,
274  Comm_pt->mpi_comm(),
275  &stat);
276  }
277 
278  // Analyse data for each point
279  for (unsigned i = 0; i < Nplot_points; i++)
280  {
281  // Somebody has found it
282  if (proc_point_found_plus_one[i] != 0)
283  {
284  // Root processor has found it
285  if (proc_point_found_plus_one[i] == 1)
286  {
287  // Copy directly from vec vector
288  data[i] = vec[i];
289  }
290  // Another (non-root) processor has found it
291  else
292  {
293  unsigned line_i = proc_point_found_plus_one[i] - 2;
294 
295  // Resize data line
296  data[i].resize(received_size[line_i][counter_s[line_i]]);
297 
298  // Copy values
299  for (unsigned j = 0;
300  j < received_size[line_i][counter_s[line_i]];
301  j++)
302  {
303  data[i][j] = received_data[line_i][counter_d[line_i] + j];
304  }
305 
306  // Increase counter
307  counter_d[line_i] += received_size[line_i][counter_s[line_i]];
308  counter_s[line_i]++;
309  }
310  } // end somebody has found it -- no output at all if nobody
311  // has found the point (e.g. outside mesh)
312  }
313  }
314  // Send data to root
315  else
316  {
317  // Send the number of fields to the main process
318  buff_size = size_values.size();
319  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag, Comm_pt->mpi_comm());
320 
321  // Send the sizes of fields to the main process
322  if (buff_size == 0) size_values.resize(1);
323  MPI_Send(&size_values[0],
324  buff_size,
325  MPI_UNSIGNED,
326  0,
327  tag,
328  Comm_pt->mpi_comm());
329 
330  // Send the number of data fields to the main process
331  buff_size = local_values.size();
332  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag, Comm_pt->mpi_comm());
333 
334  // Send the data to the main process
335  if (buff_size == 0) local_values.resize(1);
336  MPI_Send(&local_values[0],
337  buff_size,
338  MPI_DOUBLE,
339  0,
340  tag,
341  Comm_pt->mpi_comm());
342  }
343 
344 #endif // Serial version
345  }
346  }
347  else
348  {
349  // Loop over the points
350  for (unsigned i = 0; i < Nplot_points; i++)
351  {
352  // Check if the point was found in the mesh
353  if (Plot_point[i].first != NULL) // success
354  {
355  // Copy line into data array
356  Plot_point[i].first->point_output_data(Plot_point[i].second,
357  data[i]);
358  }
359  else // not found -- keep empty block there for debugging
360  {
361  // oomph_info << "Point " << i << " not found\n";
362  }
363  }
364  }
365  }
int my_rank() const
my rank
Definition: communicator.h:176
int nproc() const
number of processors
Definition: communicator.h:157
#define max(a, b)
Definition: datatypes.h:23

References Comm_pt, data, i, j, max, oomph::OomphCommunicator::my_rank(), Nplot_points, oomph::OomphCommunicator::nproc(), and Plot_point.

Referenced by output().

◆ output()

void oomph::LineVisualiser::output ( std::ostream &  outfile)
inline

Output function: output each plot point. NOTE: in a distributed problem, output is only done on processor 0.

108  {
109  // Get data in array
110  Vector<Vector<double>> data(Nplot_points);
112 
113 
114  // Loop over the points
115  for (unsigned i = 0; i < Nplot_points; i++)
116  {
117  // Get the size of the line
118  unsigned n = data[i].size();
119 
120  // Loop over the values on the line
121  for (unsigned j = 0; j < n; j++)
122  {
123  outfile << data[i][j] << " ";
124  }
125  if (n > 0)
126  {
127  outfile << std::endl;
128  }
129  }
130  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
void get_output_data(Vector< Vector< double >> &data)
Definition: line_visualiser.h:134

References data, get_output_data(), i, j, n, and Nplot_points.

◆ setup()

void oomph::LineVisualiser::setup ( Mesh mesh_pt,
const Vector< Vector< double >> &  coord_vec 
)
inlineprivate

Helper function to setup the output structures.

669  {
670  // Read out number of plot points
671  Nplot_points = coord_vec.size();
672 
673  if (Nplot_points == 0) return;
674 
675  // Keep track of unlocated plot points
676  unsigned count_not_found_local = 0;
677 
678  // Dimension
679  unsigned dim = coord_vec[0].size();
680 
681  // Make space
682  Plot_point.resize(Nplot_points);
683 
684  // Transform mesh into a geometric object
685  MeshAsGeomObject mesh_geom_tmp(mesh_pt);
686 
687  // Limit the search radius
688  mesh_geom_tmp.sample_point_container_pt()->max_search_radius() =
690 
691  // Loop over input points
692  double tt_start = TimingHelpers::timer();
693  for (unsigned i = 0; i < Nplot_points; i++)
694  {
695  // Local coordinate of the plot point with its element
696  Vector<double> s(dim, 0.0);
697 
698  // Pointer to GeomObject that contains the plot point
699  GeomObject* geom_pt = 0;
700 
701  // Locate zeta
702  mesh_geom_tmp.locate_zeta(coord_vec[i], geom_pt, s);
703 
704  // Upcast GeomElement as a FiniteElement
705  FiniteElement* fe_pt = dynamic_cast<FiniteElement*>(geom_pt);
706 
707  // Another one not found locally...
708  if (fe_pt == 0)
709  {
710  count_not_found_local++;
711  /* oomph_info << "NOT Found the one at " */
712  /* << coord_vec[i][0] << " " */
713  /* << coord_vec[i][1] << "\n"; */
714  }
715  else
716  {
717  /* oomph_info << "Found the one at " */
718  /* << coord_vec[i][0] << " " */
719  /* << coord_vec[i][1] << "\n"; */
720  }
721 
722  // Save result in a pair
723  Plot_point[i] = std::pair<FiniteElement*, Vector<double>>(fe_pt, s);
724  }
725 
726 
727  oomph_info << "Number of points not found locally: "
728  << count_not_found_local << std::endl;
729 
730  // Global equivalent (is overwritten below if mpi)
731  unsigned count_not_found = count_not_found_local;
732 
733  // Check communication pointer exists and problem is
734  // distributed.
735  if (Comm_pt != 0)
736  {
737  int nproc = Comm_pt->nproc();
738  if (nproc > 1)
739  {
740 #ifdef OOMPH_HAS_MPI
741 
742  // Declaration of MPI variables
743  int my_rank = Comm_pt->my_rank();
744 
745  // Each processor indicates if it has found a given plot point.
746  // Once this is gathered on the root processor we know
747  // exactly which data we'll receive from where.
748  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points, 0);
749 
750  // Loop over the plot points
751  for (unsigned i = 0; i < Nplot_points; i++)
752  {
753  // Found locally?
754  if (Plot_point[i].first != 0)
755  {
756  tmp_proc_point_found_plus_one[i] = my_rank + 1;
757  }
758  }
759 
760  // Gather information on root
761 
762  // Find out who's found the points
763  Vector<unsigned> proc_point_found_plus_one(Nplot_points, 0);
764  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
765  &proc_point_found_plus_one[0],
766  Nplot_points,
767  MPI_UNSIGNED,
768  MPI_MAX,
769  0,
770  Comm_pt->mpi_comm());
771 
772 
773  // Main process analyses data
774  if (my_rank == 0)
775  {
776  // Analyse data for each point
777  count_not_found = 0;
778  for (unsigned i = 0; i < Nplot_points; i++)
779  {
780  // Nobody has found it
781  if (proc_point_found_plus_one[i] == 0)
782  {
783  count_not_found++;
784  }
785  }
786  }
787 
788  // Now tell everybody about it
789  MPI_Bcast(&count_not_found, 1, MPI_UNSIGNED, 0, Comm_pt->mpi_comm());
790 
791 #endif
792  }
793  }
794  oomph_info << "Number of plot points not found (with max search radius="
795  << Max_search_radius << ")]: " << count_not_found
796  << "\nTotal time for LineVisualiser setup [sec]: "
797  << TimingHelpers::timer() - tt_start << std::endl;
798  }
RealScalar s
Definition: level1_cplx_impl.h:130
double timer()
returns the time in seconds after some point in past
Definition: oomph_utilities.cc:1295
OomphInfo oomph_info
Definition: oomph_definitions.cc:319

References Comm_pt, i, oomph::MeshAsGeomObject::locate_zeta(), Max_search_radius, SamplePointContainer::max_search_radius(), oomph::OomphCommunicator::my_rank(), Nplot_points, oomph::OomphCommunicator::nproc(), oomph::oomph_info, Plot_point, s, oomph::MeshAsGeomObject::sample_point_container_pt(), and oomph::TimingHelpers::timer().

Referenced by LineVisualiser(), and setup_from_file().

◆ setup_from_file()

void oomph::LineVisualiser::setup_from_file ( Mesh mesh_pt,
const std::string  file_name,
const double scale 
)
inlineprivate

Helper function to setup from file.

606  {
607  // Open file use ifstream
608  std::ifstream file_input(file_name.c_str(), std::ios_base::in);
609  if (!file_input)
610  {
611  std::ostringstream error_message;
612  error_message << "Cannot open file " << file_name << "\n";
613  throw OomphLibError(error_message.str(),
616  }
617  if (!file_input.is_open())
618  {
619  std::ostringstream error_message;
620  error_message << "Cannot open file " << file_name << "\n";
621  throw OomphLibError(error_message.str(),
624  }
625 
626  // Declaration of variables
628  Vector<Vector<double>> coord_vec_tmp; // Coord array
629 
630  // Loop over the lines of the input file
631  while (getline(file_input, line) /* != 0*/)
632  {
633  // Test if the first char of the line is a number
634  // using ascii enumeration of chars
635  if (isdigit(line[0]))
636  {
637  Vector<double> tmp(3);
638 
639  // Read the 3 first doubles of the line
640  // Return 3 if success and less if error
641  int n =
642  sscanf(line.c_str(), "%lf %lf %lf", &tmp[0], &tmp[1], &tmp[2]);
643 
644  if (n == 3) // success
645  {
646  // Rescaling
647  for (unsigned i = 0; i < 3; i++)
648  {
649  tmp[i] *= scale;
650  }
651 
652  // Add the new point to the list
653  coord_vec_tmp.push_back(tmp);
654  }
655  else // error
656  {
657  oomph_info << "Line ignored \n";
658  }
659  }
660  }
661 
662  // Call to the helper function
663  setup(mesh_pt, coord_vec_tmp);
664  }
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
line
Definition: calibrate.py:103
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Particles2023AnalysisHung::file_name, i, calibrate::line, n, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, oomph::oomph_info, setup(), oomph::Global_string_for_annotation::string(), and tmp.

Referenced by LineVisualiser().

◆ update_plot_points_coordinates()

void oomph::LineVisualiser::update_plot_points_coordinates ( Vector< Vector< double >> &  coord_vec)
inline

Update plot points coordinates (in preparation of remesh, say).

371  {
372  // Resize coord_vec
373  coord_vec.resize(Nplot_points);
374 
375  // Check that the communication pointer is initialised and the
376  // problem is distributed.
377  if (Comm_pt != 0)
378  {
379  int nproc = Comm_pt->nproc();
380  if (nproc > 1)
381  {
382 #ifdef OOMPH_HAS_MPI
383 
384  // Declaration of MPI variables
385  MPI_Status stat;
386  int tag; // cgj: tag should be initialised before use
387  int my_rank = Comm_pt->my_rank();
388 
389 
390  // Buffer
391  unsigned buff_size;
392 
393  // Create array which contains data found in every process
394  Vector<Vector<double>> vec(Nplot_points);
395 
396  for (unsigned i = 0; i < Nplot_points; i++)
397  {
398  if (Plot_point[i].first != NULL)
399  {
400  if (!((*Plot_point[i].first).is_halo()))
401  {
402  unsigned dim = Plot_point[i].second.size();
403 
404  vec[i].resize(dim);
405 
406  for (unsigned j = 0; j < dim; j++)
407  {
408  vec[i][j] = Plot_point[i].first->interpolated_x(
409  Plot_point[i].second, j);
410  }
411  }
412  }
413  }
414 
415 
416  // Analyse which plot points have been found
417  // locally and concatenate the data:
418 
419  // This contains the flat-packed doubles to be sent
420  // for all located plot points
421  Vector<double> local_values;
422 
423  // Number of values to be sent for each plot point
424  // (almost certainly the same for all plot points, but...)
425  // size_values[i] gives the number of doubles to be
426  // sent for plot point i.
427  Vector<unsigned> size_values;
428 
429  // Each processor indicates if it has found a given plot point.
430  // Once this is gathered on the root processor we know
431  // exactly which data we'll receive from where.
432  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points, 0);
433 
434  // Loop over the plot points
435  for (unsigned i = 0; i < Nplot_points; i++)
436  {
437  unsigned ndata = vec[i].size();
438  if (ndata != 0)
439  {
440  // Store the number of fields
441  size_values.push_back(ndata);
442 
443  // Update found vector
444  tmp_proc_point_found_plus_one[i] = my_rank + 1;
445 
446 
447  // Store values
448  for (unsigned j = 0; j < ndata; j++)
449  {
450  local_values.push_back(vec[i][j]);
451  }
452  }
453  }
454 
455  // Gather information on root
456 
457  // Find out who's found the points
458  Vector<unsigned> proc_point_found_plus_one(Nplot_points, 0);
459  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
460  &proc_point_found_plus_one[0],
461  Nplot_points,
462  MPI_UNSIGNED,
463  MPI_MAX,
464  0,
465  Comm_pt->mpi_comm());
466 
467  // Main process write data
468  if (my_rank == 0)
469  {
470  // Collect all the data
471  Vector<Vector<double>> received_data(nproc - 1);
472  Vector<Vector<unsigned>> received_size(nproc - 1);
473  Vector<unsigned> counter_d(nproc - 1, 0);
474  Vector<unsigned> counter_s(nproc - 1, 0);
475 
476  // Loop over processors that send their points
477  for (int i = 1; i < nproc; i++)
478  {
479  // Receive sizes of data
480  MPI_Recv(&buff_size,
481  1,
482  MPI_UNSIGNED,
483  i,
484  tag,
485  Comm_pt->mpi_comm(),
486  &stat);
487  received_size[i - 1].resize(std::max(unsigned(1), buff_size));
488  MPI_Recv(&received_size[i - 1][0],
489  buff_size,
490  MPI_UNSIGNED,
491  i,
492  tag,
493  Comm_pt->mpi_comm(),
494  &stat);
495 
496  // Receive actual data
497  MPI_Recv(&buff_size,
498  1,
499  MPI_UNSIGNED,
500  i,
501  tag,
502  Comm_pt->mpi_comm(),
503  &stat);
504  received_data[i - 1].resize(std::max(unsigned(1), buff_size));
505  MPI_Recv(&received_data[i - 1][0],
506  buff_size,
507  MPI_DOUBLE,
508  i,
509  tag,
510  Comm_pt->mpi_comm(),
511  &stat);
512  }
513 
514  // Analyse data for each point
515  for (unsigned i = 0; i < Nplot_points; i++)
516  {
517  // Somebody has found it
518  if (proc_point_found_plus_one[i] != 0)
519  {
520  // Root processor has found it
521  if (proc_point_found_plus_one[i] == 1)
522  {
523  // Copy directly from vec vector
524  coord_vec[i] = vec[i];
525  }
526  // Another (non-root) processor has found it
527  else
528  {
529  unsigned line_i = proc_point_found_plus_one[i] - 2;
530 
531  // Resize data line
532  coord_vec[i].resize(received_size[line_i][counter_s[line_i]]);
533 
534  // Copy values
535  for (unsigned j = 0;
536  j < received_size[line_i][counter_s[line_i]];
537  j++)
538  {
539  coord_vec[i][j] =
540  received_data[line_i][counter_d[line_i] + j];
541  }
542 
543  // Increase counter
544  counter_d[line_i] += received_size[line_i][counter_s[line_i]];
545  counter_s[line_i]++;
546  }
547  } // end somebody has found it -- no output at all if nobody
548  // has found the point (e.g. outside mesh)
549  }
550  }
551  // Send data to root
552  else
553  {
554  // Send the number of fields to the main process
555  buff_size = size_values.size();
556  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag, Comm_pt->mpi_comm());
557 
558  // Send the sizes of fields to the main process
559  if (buff_size == 0) size_values.resize(1);
560  MPI_Send(&size_values[0],
561  buff_size,
562  MPI_UNSIGNED,
563  0,
564  tag,
565  Comm_pt->mpi_comm());
566 
567  // Send the number of data fields to the main process
568  buff_size = local_values.size();
569  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag, Comm_pt->mpi_comm());
570 
571  // Send the data to the main process
572  if (buff_size == 0) local_values.resize(1);
573  MPI_Send(&local_values[0],
574  buff_size,
575  MPI_DOUBLE,
576  0,
577  tag,
578  Comm_pt->mpi_comm());
579  }
580 
581 #endif // Serial version
582  }
583  }
584  else
585  {
587  }
588  }
void get_local_plot_points_coordinates(Vector< Vector< double >> &data)
Definition: line_visualiser.h:801

References Comm_pt, get_local_plot_points_coordinates(), i, j, max, oomph::OomphCommunicator::my_rank(), Nplot_points, oomph::OomphCommunicator::nproc(), and Plot_point.

Member Data Documentation

◆ Comm_pt

OomphCommunicator* oomph::LineVisualiser::Comm_pt
private

Pointer to communicator – allows us to collect data on processor 0 if the mesh is distributed.

Referenced by get_output_data(), setup(), and update_plot_points_coordinates().

◆ Max_search_radius

double oomph::LineVisualiser::Max_search_radius
private

Max radius beyond which we stop searching the bin. Initialised to DBL_MAX so keep going until the point is found or until we've searched every single bin. Overwriting this means we won't search in bins whose closest vertex is at a distance greater than Max_search_radius from the point to be located.

Referenced by setup().

◆ Nplot_points

unsigned oomph::LineVisualiser::Nplot_points
private

◆ Plot_point

Vector<std::pair<FiniteElement*, Vector<double> > > oomph::LineVisualiser::Plot_point
private

Vector of pairs containing points to finite elements and local coordinates

Referenced by get_local_plot_points_coordinates(), get_output_data(), setup(), and update_plot_points_coordinates().


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