line_visualiser.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for line visualiser
31 
32 //Include guard to prevent multiple inclusions of the header
33 #ifndef OOMPH_LINE_VISUALISER_HEADER
34 #define OOMPH_LINE_VISUALISER_HEADER
35 
36 // Config header generated by autoconfig
37 #ifdef HAVE_CONFIG_H
38 #include <oomph-lib-config.h>
39 #endif
40 
41 #include<fstream>
42 #include<iostream>
43 
44 
45 namespace oomph
46 {
47 
48 //====================================================================
49 /// \short Class to aid visualisation of the values on a set
50 /// of points. NOTE: in a distributed problem, output is only done
51 /// on processor 0.
52 //====================================================================
54  {
55 
56  public :
57 
58 
59  /// \short Constructor: Pass pointer to mesh and coordinates of
60  /// desired plot points: coord_vec[j][i] is the i-th coordinate of
61  /// the j-th plot point. Optional final parameter specifies the
62  /// maximum search radius in bin when locating the plot points.
63  /// Defaults to DBL_MAX and will therefore keep searching through
64  /// the entire bin structure if a point cannot be found. It's worth
65  /// limiting this to the order of the size of a typical element
66  /// in the mesh in parallel computations with fine meshes, otherwise
67  /// the setup can take forever.
68  LineVisualiser(Mesh* mesh_pt, const Vector<Vector<double> >& coord_vec,
69  const double& max_search_radius=DBL_MAX) :
70  Max_search_radius(max_search_radius),
71  Comm_pt(mesh_pt->communicator_pt())
72  {
73  // Do the actual work
74  setup(mesh_pt,coord_vec);
75  }
76 
77 
78  /// \short Constructor reading centerline file
79  /// - Open "file_name" and extract 3 first doubles of each line
80  /// - Skip lines which does not begin with a number. Scaling
81  /// factor allows points defined in input file to be scaled.
82  LineVisualiser(Mesh* mesh_pt, const std::string file_name,
83  const double &scale = 1.0) :
84  Max_search_radius(DBL_MAX),
85  Comm_pt(mesh_pt->communicator_pt())
86  {
87  setup_from_file(mesh_pt,file_name,scale);
88  }
89 
90 
91  /// \short Constructor reading centerline file
92  /// - Open "file_name" and extract 3 first doubles of each line
93  /// - Skip lines which does not begin with a number. Scaling
94  /// factor allows points defined in input file to be scaled.
95  /// Second parameter specifies the
96  /// maximum search radius in bin when locating the plot points. It's worth
97  /// setting this to the order of the size of a typical element
98  /// in the mesh in parallel computations with fine meshes, otherwise
99  /// the setup can take forever.
100  LineVisualiser(Mesh* mesh_pt, const double& max_search_radius,
101  const std::string file_name, const double &scale = 1.0) :
102  Max_search_radius(max_search_radius),
103  Comm_pt(mesh_pt->communicator_pt())
104  {
105  setup_from_file(mesh_pt,file_name,scale);
106  }
107 
108 
109 
110 
111  /// \short Output function: output each plot point.
112  /// NOTE: in a distributed problem, output is only done
113  /// on processor 0.
114  void output(std::ostream &outfile)
115  {
116  // Get data in array
118  get_output_data(data);
119 
120 
121  // Loop over the points
122  for (unsigned i=0; i<Nplot_points; i++)
123  {
124  // Get the size of the line
125  unsigned n=data[i].size();
126 
127  // Loop over the values on the line
128  for (unsigned j=0;j<n;j++)
129  {
130  outfile << data[i][j] << " ";
131  }
132  if (n > 0)
133  {
134  outfile << std::endl;
135  }
136  }
137  }
138 
139  /// \short Output data function: store data associated with each
140  /// plot point in data array
142  {
143  // Resize output data array
144  data.resize(Nplot_points);
145 
146  // Check if mesh is distributed and a communication pointer
147  // exists.
148  if(Comm_pt!=0)
149  {
150  int nproc=Comm_pt->nproc();
151 
152  if (nproc>1)
153  {
154 
155 #ifdef OOMPH_HAS_MPI
156 
157  // Declaration of MPI variables
158  MPI_Status stat;
159  int tag=0;
160  int my_rank=Comm_pt->my_rank();
161 
162 
163  // Buffer
164  unsigned buff_size;
165 
166  // Create array which contains data found in every process
168 
169  // Loop over the points to fill in vec
170  for (unsigned i=0; i<Nplot_points; i++)
171  {
172  // Check if the point was found in the mesh
173  if (Plot_point[i].first != NULL) // success
174  {
175  // Check if the point is halo
176  if (!((*Plot_point[i].first).is_halo()))
177  {
178  // Get the line of output data from the element
179  // (specified by .first), at its local coordinate
180  // (specified by .second)
181  Plot_point[i].first->point_output_data(Plot_point[i].second,
182  vec[i]);
183  }
184  }
185  }
186 
187 
188  // Analyse which plot points have been found
189  // locally and concatenate the data:
190 
191  // This contains the flat-packed doubles to be sent
192  // for all located plot points
193  Vector<double> local_values;
194 
195  // Number of values to be sent for each plot point
196  // (almost certainly the same for all plot points, but...)
197  // size_values[i] gives the number of doubles to be
198  // sent for plot point i.
199  Vector<unsigned> size_values;
200 
201  // Each processor indicates if it has found a given plot point.
202  // Once this is gathered on the root processor we know
203  // exactly which data we'll receive from where.
204  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points,0);
205 
206  // Loop over the plot points
207  for (unsigned i=0; i<Nplot_points; i++)
208  {
209  unsigned ndata=vec[i].size();
210  if (ndata!=0)
211  {
212  // Store the number of fields
213  size_values.push_back(ndata);
214 
215  // Update found vector
216  tmp_proc_point_found_plus_one[i]=my_rank+1;
217 
218  // Store values
219  for (unsigned j=0;j<ndata;j++)
220  {
221  local_values.push_back(vec[i][j]);
222  }
223  }
224  }
225 
226  // Gather information on root
227 
228  // Find out who's found the points
229  Vector<unsigned> proc_point_found_plus_one(Nplot_points,0);
230  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
231  &proc_point_found_plus_one[0],
232  Nplot_points, MPI_UNSIGNED, MPI_MAX, 0,
233  Comm_pt->mpi_comm());
234 
235 
236  // Main process write data
237  if (my_rank == 0)
238  {
239  // Collect all the data
240  Vector<Vector<double> > received_data(nproc-1);
241  Vector<Vector<unsigned> > received_size(nproc-1);
242  Vector<unsigned> counter_d(nproc-1,0);
243  Vector<unsigned> counter_s(nproc-1,0);
244 
245  // Loop over processors that send their points
246  for (int i=1; i<nproc; i++)
247  {
248  // Receive sizes of data
249  MPI_Recv(&buff_size, 1, MPI_UNSIGNED, i,
250  tag, Comm_pt->mpi_comm(), &stat);
251  received_size[i-1].resize(std::max(unsigned(1),buff_size));
252  MPI_Recv(&received_size[i-1][0], buff_size, MPI_UNSIGNED, i,
253  tag, Comm_pt->mpi_comm(), &stat);
254 
255  // Receive actual data
256  MPI_Recv(&buff_size, 1, MPI_UNSIGNED, i,
257  tag, Comm_pt->mpi_comm(), &stat);
258  received_data[i-1].resize(std::max(unsigned(1),buff_size));
259  MPI_Recv(&received_data[i-1][0], buff_size, MPI_DOUBLE, i,
260  tag, Comm_pt->mpi_comm(), &stat);
261  }
262 
263  // Analyse data for each point
264  for (unsigned i=0; i<Nplot_points; i++)
265  {
266  // Somebody has found it
267  if (proc_point_found_plus_one[i] != 0)
268  {
269  // Root processor has found it
270  if (proc_point_found_plus_one[i] == 1)
271  {
272  // Copy directly from vec vector
273  data[i]=vec[i];
274  }
275  // Another (non-root) processor has found it
276  else
277  {
278  unsigned line_i=proc_point_found_plus_one[i]-2;
279 
280  // Resize data line
281  data[i].resize(received_size[line_i][counter_s[line_i] ]);
282 
283  // Copy values
284  for (unsigned j=0;j<received_size[line_i][counter_s[line_i] ];
285  j++)
286  {
287  data[i][j]=received_data[line_i][counter_d[line_i]+j];
288  }
289 
290  //Increase counter
291  counter_d[line_i]+=received_size[line_i][counter_s[line_i] ];
292  counter_s[line_i]++;
293  }
294  } // end somebody has found it -- no output at all if nobody
295  // has found the point (e.g. outside mesh)
296  }
297  }
298  // Send data to root
299  else
300  {
301  //Send the number of fields to the main process
302  buff_size = size_values.size();
303  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag,
304  Comm_pt->mpi_comm());
305 
306  //Send the sizes of fields to the main process
307  if (buff_size==0) size_values.resize(1);
308  MPI_Send(&size_values[0], buff_size, MPI_UNSIGNED, 0, tag,
309  Comm_pt->mpi_comm());
310 
311  //Send the number of data fields to the main process
312  buff_size = local_values.size();
313  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag,
314  Comm_pt->mpi_comm());
315 
316  //Send the data to the main process
317  if (buff_size==0) local_values.resize(1);
318  MPI_Send(&local_values[0], buff_size, MPI_DOUBLE, 0, tag,
319  Comm_pt->mpi_comm());
320  }
321 
322 #endif // Serial version
323  }
324  }
325  else
326  {
327 
328  // Loop over the points
329  for (unsigned i=0; i<Nplot_points; i++)
330  {
331  // Check if the point was found in the mesh
332  if (Plot_point[i].first != NULL) // success
333  {
334  // Copy line into data array
335  Plot_point[i].first->point_output_data(Plot_point[i].second,
336  data[i]);
337  }
338  else // not found -- keep empty block there for debugging
339  {
340  //oomph_info << "Point " << i << " not found\n";
341  }
342  }
343  }
344  }
345 
346 
347  /// \short Update plot points coordinates (in preparation of remesh,
348  /// say).
350  {
351  // Resize coord_vec
352  coord_vec.resize(Nplot_points);
353 
354  // Check that the communication pointer is initialised and the
355  // problem is distributed.
356  if(Comm_pt!=0)
357  {
358  int nproc=Comm_pt->nproc();
359  if (nproc>1)
360  {
361 
362 #ifdef OOMPH_HAS_MPI
363 
364  // Declaration of MPI variables
365  MPI_Status stat;
366  int tag; // cgj: tag should be initialised before use
367  int my_rank=Comm_pt->my_rank();
368 
369 
370  // Buffer
371  unsigned buff_size;
372 
373  // Create array which contains data found in every process
375 
376  for (unsigned i=0; i<Nplot_points; i++)
377  {
378  if (Plot_point[i].first != NULL)
379  {
380  if (!((*Plot_point[i].first).is_halo()))
381  {
382  unsigned dim = Plot_point[i].second.size();
383 
384  vec[i].resize(dim);
385 
386  for (unsigned j=0; j<dim; j++)
387  {
388  vec[i][j]=Plot_point[i].first->
389  interpolated_x(Plot_point[i].second,j);
390  }
391  }
392  }
393  }
394 
395 
396  // Analyse which plot points have been found
397  // locally and concatenate the data:
398 
399  // This contains the flat-packed doubles to be sent
400  // for all located plot points
401  Vector<double> local_values;
402 
403  // Number of values to be sent for each plot point
404  // (almost certainly the same for all plot points, but...)
405  // size_values[i] gives the number of doubles to be
406  // sent for plot point i.
407  Vector<unsigned> size_values;
408 
409  // Each processor indicates if it has found a given plot point.
410  // Once this is gathered on the root processor we know
411  // exactly which data we'll receive from where.
412  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points,0);
413 
414  // Loop over the plot points
415  for (unsigned i=0; i<Nplot_points; i++)
416  {
417  unsigned ndata=vec[i].size();
418  if (ndata!=0)
419  {
420  // Store the number of fields
421  size_values.push_back(ndata);
422 
423  // Update found vector
424  tmp_proc_point_found_plus_one[i]=my_rank+1;
425 
426 
427  // Store values
428  for (unsigned j=0;j<ndata;j++)
429  {
430  local_values.push_back(vec[i][j]);
431  }
432  }
433  }
434 
435  // Gather information on root
436 
437  // Find out who's found the points
438  Vector<unsigned> proc_point_found_plus_one(Nplot_points,0);
439  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
440  &proc_point_found_plus_one[0],
441  Nplot_points, MPI_UNSIGNED, MPI_MAX, 0,
442  Comm_pt->mpi_comm());
443 
444  // Main process write data
445  if (my_rank == 0)
446  {
447  // Collect all the data
448  Vector<Vector<double> > received_data(nproc-1);
449  Vector<Vector<unsigned> > received_size(nproc-1);
450  Vector<unsigned> counter_d(nproc-1,0);
451  Vector<unsigned> counter_s(nproc-1,0);
452 
453  // Loop over processors that send their points
454  for (int i=1; i<nproc; i++)
455  {
456  // Receive sizes of data
457  MPI_Recv(&buff_size, 1, MPI_UNSIGNED, i,
458  tag, Comm_pt->mpi_comm(), &stat);
459  received_size[i-1].resize(std::max(unsigned(1),buff_size));
460  MPI_Recv(&received_size[i-1][0], buff_size, MPI_UNSIGNED, i,
461  tag, Comm_pt->mpi_comm(), &stat);
462 
463  // Receive actual data
464  MPI_Recv(&buff_size, 1, MPI_UNSIGNED, i,
465  tag, Comm_pt->mpi_comm(), &stat);
466  received_data[i-1].resize(std::max(unsigned(1),buff_size));
467  MPI_Recv(&received_data[i-1][0], buff_size, MPI_DOUBLE, i,
468  tag, Comm_pt->mpi_comm(), &stat);
469  }
470 
471  // Analyse data for each point
472  for (unsigned i=0; i<Nplot_points; i++)
473  {
474  // Somebody has found it
475  if (proc_point_found_plus_one[i] != 0)
476  {
477  // Root processor has found it
478  if (proc_point_found_plus_one[i] == 1)
479  {
480  // Copy directly from vec vector
481  coord_vec[i]=vec[i];
482  }
483  // Another (non-root) processor has found it
484  else
485  {
486  unsigned line_i=proc_point_found_plus_one[i]-2;
487 
488  // Resize data line
489  coord_vec[i].resize(received_size[line_i][counter_s[line_i] ]);
490 
491  // Copy values
492  for (unsigned j=0;j<received_size[line_i][counter_s[line_i] ];
493  j++)
494  {
495  coord_vec[i][j]=received_data[line_i][counter_d[line_i]+j];
496  }
497 
498  //Increase counter
499  counter_d[line_i]+=received_size[line_i][counter_s[line_i] ];
500  counter_s[line_i]++;
501  }
502  } // end somebody has found it -- no output at all if nobody
503  // has found the point (e.g. outside mesh)
504  }
505  }
506  // Send data to root
507  else
508  {
509  //Send the number of fields to the main process
510  buff_size = size_values.size();
511  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag,
512  Comm_pt->mpi_comm());
513 
514  //Send the sizes of fields to the main process
515  if (buff_size==0) size_values.resize(1);
516  MPI_Send(&size_values[0], buff_size, MPI_UNSIGNED, 0, tag,
517  Comm_pt->mpi_comm());
518 
519  //Send the number of data fields to the main process
520  buff_size = local_values.size();
521  MPI_Send(&buff_size, 1, MPI_UNSIGNED, 0, tag,
522  Comm_pt->mpi_comm());
523 
524  //Send the data to the main process
525  if (buff_size==0) local_values.resize(1);
526  MPI_Send(&local_values[0], buff_size, MPI_DOUBLE, 0, tag,
527  Comm_pt->mpi_comm());
528  }
529 
530 #endif // Serial version
531  }
532  }
533  else
534  {
536  }
537  }
538 
539  private:
540 
541  /// \short Max radius beyond which we stop searching the bin. Initialised
542  /// to DBL_MAX so keep going until the point is found or until
543  /// we've searched every single bin. Overwriting this means we won't search
544  /// in bins whose closest vertex is at a distance greater than
545  /// Max_search_radius from the point to be located.
547 
548  /// \short Pointer to communicator -- allows us to collect data on
549  /// processor 0 if the mesh is distributed.
551 
552  /// Helper function to setup from file
553  void setup_from_file(Mesh* mesh_pt, const std::string file_name,
554  const double &scale)
555  {
556  // Open file use ifstream
557  std::ifstream file_input(file_name.c_str(),std::ios_base::in);
558  if (!file_input)
559  {
560  std::ostringstream error_message;
561  error_message << "Cannot open file " << file_name << "\n";
562  throw OomphLibError(error_message.str(),
563  OOMPH_CURRENT_FUNCTION,
564  OOMPH_EXCEPTION_LOCATION);
565  }
566  if (!file_input.is_open())
567  {
568  std::ostringstream error_message;
569  error_message << "Cannot open file " << file_name << "\n";
570  throw OomphLibError(error_message.str(),
571  OOMPH_CURRENT_FUNCTION,
572  OOMPH_EXCEPTION_LOCATION);
573  }
574 
575  // Declaration of variables
576  std::string line;
577  Vector<Vector<double> > coord_vec_tmp; // Coord array
578 
579  // Loop over the lines of the input file
580  while(getline(file_input,line)/* != 0*/)
581  {
582  // Test if the first char of the line is a number
583  // using ascii enumeration of chars
584  if (isdigit(line[0]))
585  {
586  Vector<double> tmp(3);
587 
588  // Read the 3 first doubles of the line
589  // Return 3 if success and less if error
590  int n=sscanf(line.c_str(),"%lf %lf %lf",&tmp[0],&tmp[1],&tmp[2]);
591 
592  if (n == 3) // success
593  {
594  // Rescaling
595  for (unsigned i=0; i<3; i++)
596  {
597  tmp[i]*=scale;
598  }
599 
600  // Add the new point to the list
601  coord_vec_tmp.push_back(tmp);
602  }
603  else // error
604  {
605  oomph_info << "Line ignored \n";
606  }
607  }
608  }
609 
610  // Call to the helper function
611  setup(mesh_pt,coord_vec_tmp);
612  }
613 
614 
615 
616  /// \short Helper function to setup the output structures
617  void setup(Mesh* mesh_pt, const Vector<Vector<double> > &coord_vec)
618  {
619  // Read out number of plot points
620  Nplot_points=coord_vec.size();
621 
622  if (Nplot_points==0) return;
623 
624  // Keep track of unlocated plot points
625  unsigned count_not_found_local=0;
626 
627  // Dimension
628  unsigned dim=coord_vec[0].size();
629 
630  // Make space
631  Plot_point.resize(Nplot_points);
632 
633  // Transform mesh into a geometric object
634  MeshAsGeomObject mesh_geom_tmp(mesh_pt);
635 
636  // Limit the search radius
637  mesh_geom_tmp.sample_point_container_pt()->max_search_radius()=
639 
640  // Loop over input points
641  double tt_start=TimingHelpers::timer();
642  for (unsigned i=0; i<Nplot_points; i++)
643  {
644  // Local coordinate of the plot point with its element
645  Vector<double> s(dim,0.0);
646 
647  // Pointer to GeomObject that contains the plot point
648  GeomObject* geom_pt=0;
649 
650  // Locate zeta
651  mesh_geom_tmp.locate_zeta(coord_vec[i],geom_pt,s);
652 
653  // Upcast GeomElement as a FiniteElement
654  FiniteElement* fe_pt=dynamic_cast<FiniteElement*>(geom_pt);
655 
656  // Another one not found locally...
657  if (fe_pt==0)
658  {
659  count_not_found_local++;
660  /* oomph_info << "NOT Found the one at " */
661  /* << coord_vec[i][0] << " " */
662  /* << coord_vec[i][1] << "\n"; */
663  }
664  else
665  {
666  /* oomph_info << "Found the one at " */
667  /* << coord_vec[i][0] << " " */
668  /* << coord_vec[i][1] << "\n"; */
669  }
670 
671  // Save result in a pair
672  Plot_point[i]=std::pair<FiniteElement*,Vector<double> >(fe_pt,s);
673  }
674 
675 
676  oomph_info << "Number of points not found locally: "
677  << count_not_found_local << std::endl;
678 
679  // Global equivalent (is overwritten below if mpi)
680  unsigned count_not_found=count_not_found_local;
681 
682  // Check communication pointer exists and problem is
683  // distributed.
684  if(Comm_pt!=0)
685  {
686  int nproc=Comm_pt->nproc();
687  if (nproc>1)
688  {
689 
690 #ifdef OOMPH_HAS_MPI
691 
692  // Declaration of MPI variables
693  int my_rank=Comm_pt->my_rank();
694 
695  // Each processor indicates if it has found a given plot point.
696  // Once this is gathered on the root processor we know
697  // exactly which data we'll receive from where.
698  Vector<unsigned> tmp_proc_point_found_plus_one(Nplot_points,0);
699 
700  // Loop over the plot points
701  for (unsigned i=0; i<Nplot_points; i++)
702  {
703  // Found locally?
704  if (Plot_point[i].first!=0)
705  {
706  tmp_proc_point_found_plus_one[i]=my_rank+1;
707  }
708  }
709 
710  // Gather information on root
711 
712  // Find out who's found the points
713  Vector<unsigned> proc_point_found_plus_one(Nplot_points,0);
714  MPI_Reduce(&tmp_proc_point_found_plus_one[0],
715  &proc_point_found_plus_one[0],
716  Nplot_points, MPI_UNSIGNED, MPI_MAX, 0,
717  Comm_pt->mpi_comm());
718 
719 
720  // Main process analyses data
721  if (my_rank == 0)
722  {
723  // Analyse data for each point
724  count_not_found=0;
725  for (unsigned i=0; i<Nplot_points; i++)
726  {
727  // Nobody has found it
728  if (proc_point_found_plus_one[i] == 0)
729  {
730  count_not_found++;
731  }
732  }
733  }
734 
735  // Now tell everybody about it
736  MPI_Bcast(&count_not_found,1,MPI_UNSIGNED,0,
737  Comm_pt->mpi_comm());
738 
739 #endif
740  }
741  }
742  double tt_end=TimingHelpers::timer();
743  oomph_info
744  << "Total time for location of plot points in LineVisualiser: "
745  << tt_end-tt_start << " [" << count_not_found
746  << " plot points were not found (with max search radius="
747  << Max_search_radius << ")]\n";
748  }
749 
750  // Get coordinates of found points
752  {
753  data.resize(Nplot_points);
754  for (unsigned i=0; i<Nplot_points; i++)
755  {
756  if (Plot_point[i].first != NULL)
757  {
758  unsigned dim = Plot_point[i].second.size();
759 
760  data[i].resize(dim);
761 
762  for (unsigned j=0; j<dim; j++)
763  {
764  data[i][j]=Plot_point[i].first->interpolated_x(
765  Plot_point[i].second,j);
766  }
767  }
768  }
769 
770  }
771 
772 
773  /// \short Vector of pairs containing points to finite elements and
774  /// local coordinates
776 
777  /// Number of plot points
778  unsigned Nplot_points;
779 
780  }; //end of class
781 
782 }
783 
784 #endif
785 
void setup_from_file(Mesh *mesh_pt, const std::string file_name, const double &scale)
Helper function to setup from file.
SamplePointContainer * sample_point_container_pt() const
Pointer to the sample point container.
unsigned Nplot_points
Number of plot points.
cstr elem_len * i
Definition: cfortran.h:607
LineVisualiser(Mesh *mesh_pt, const double &max_search_radius, const std::string file_name, const double &scale=1.0)
Constructor reading centerline file.
A general Finite Element class.
Definition: elements.h:1274
double Max_search_radius
Max radius beyond which we stop searching the bin. Initialised to DBL_MAX so keep going until the poi...
void locate_zeta(const Vector< double > &zeta, GeomObject *&sub_geom_object_pt, Vector< double > &s, const bool &use_coordinate_as_initial_guess=false)
Find the sub geometric object and local coordinate therein that corresponds to the intrinsic coordina...
void update_plot_points_coordinates(Vector< Vector< double > > &coord_vec)
Update plot points coordinates (in preparation of remesh, say).
OomphInfo oomph_info
Class to aid visualisation of the values on a set of points. NOTE: in a distributed problem...
void get_output_data(Vector< Vector< double > > &data)
Output data function: store data associated with each plot point in data array.
void get_local_plot_points_coordinates(Vector< Vector< double > > &data)
static char t char * s
Definition: cfortran.h:572
LineVisualiser(Mesh *mesh_pt, const std::string file_name, const double &scale=1.0)
Constructor reading centerline file.
double timer()
returns the time in seconds after some point in past
void setup(Mesh *mesh_pt, const Vector< Vector< double > > &coord_vec)
Helper function to setup the output structures.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
OomphCommunicator * Comm_pt
Pointer to communicator – allows us to collect data on processor 0 if the mesh is distributed...
Vector< std::pair< FiniteElement *, Vector< double > > > Plot_point
Vector of pairs containing points to finite elements and local coordinates.
double & max_search_radius()
Set maximum search radius for locate zeta. This is initialised do DBL_MAX so we brutally search throu...
void output(std::ostream &outfile)
Output function: output each plot point. NOTE: in a distributed problem, output is only done on proce...
A general mesh class.
Definition: mesh.h:74
LineVisualiser(Mesh *mesh_pt, const Vector< Vector< double > > &coord_vec, const double &max_search_radius=DBL_MAX)
Constructor: Pass pointer to mesh and coordinates of desired plot points: coord_vec[j][i] is the i-th...
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:57