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// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26// Header file for line visualiser
27
28// Include guard to prevent multiple inclusions of the header
29#ifndef OOMPH_LINE_VISUALISER_HEADER
30#define OOMPH_LINE_VISUALISER_HEADER
31
32// Config header generated by autoconfig
33#ifdef HAVE_CONFIG_H
34#include <oomph-lib-config.h>
35#endif
36
37#include <fstream>
38#include <iostream>
39
40
41namespace oomph
42{
43 //====================================================================
44 /// Class to aid visualisation of the values on a set
45 /// of points. NOTE: in a distributed problem, output is only done
46 /// on processor 0.
47 //====================================================================
49 {
50 public:
51 /// Constructor: Pass pointer to mesh and coordinates of
52 /// desired plot points: coord_vec[j][i] is the i-th coordinate of
53 /// the j-th plot point. Optional final parameter specifies the
54 /// maximum search radius in bin when locating the plot points.
55 /// Defaults to DBL_MAX and will therefore keep searching through
56 /// the entire bin structure if a point cannot be found. It's worth
57 /// limiting this to the order of the size of a typical element
58 /// in the mesh in parallel computations with fine meshes, otherwise
59 /// the setup can take forever.
61 const Vector<Vector<double>>& coord_vec,
62 const double& max_search_radius = DBL_MAX)
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 }
69
70
71 /// Constructor reading centerline file
72 /// - Open "file_name" and extract 3 first doubles of each line
73 /// - Skip lines which does not begin with a number. Scaling
74 /// factor allows points defined in input file to be scaled.
76 const std::string file_name,
77 const double& scale = 1.0)
78 : Max_search_radius(DBL_MAX), Comm_pt(mesh_pt->communicator_pt())
79 {
80 setup_from_file(mesh_pt, file_name, scale);
81 }
82
83
84 /// Constructor reading centerline file
85 /// - Open "file_name" and extract 3 first doubles of each line
86 /// - Skip lines which does not begin with a number. Scaling
87 /// factor allows points defined in input file to be scaled.
88 /// Second parameter specifies the
89 /// maximum search radius in bin when locating the plot points. It's worth
90 /// setting this to the order of the size of a typical element
91 /// in the mesh in parallel computations with fine meshes, otherwise
92 /// the setup can take forever.
94 const double& max_search_radius,
95 const std::string file_name,
96 const double& scale = 1.0)
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 }
102
103
104 /// Output function: output each plot point.
105 /// NOTE: in a distributed problem, output is only done
106 /// on processor 0.
107 void output(std::ostream& outfile)
108 {
109 // Get data in array
111 get_output_data(data);
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 }
131
132 /// Output data function: store data associated with each
133 /// 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
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],
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 }
366
367
368 /// Update plot points coordinates (in preparation of remesh,
369 /// 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
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],
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 }
589
590 private:
591 /// Max radius beyond which we stop searching the bin. Initialised
592 /// to DBL_MAX so keep going until the point is found or until
593 /// we've searched every single bin. Overwriting this means we won't search
594 /// in bins whose closest vertex is at a distance greater than
595 /// Max_search_radius from the point to be located.
597
598 /// Pointer to communicator -- allows us to collect data on
599 /// processor 0 if the mesh is distributed.
601
602 /// Helper function to setup from file
603 void setup_from_file(Mesh* mesh_pt,
604 const std::string file_name,
605 const double& scale)
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(),
614 OOMPH_CURRENT_FUNCTION,
615 OOMPH_EXCEPTION_LOCATION);
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(),
622 OOMPH_CURRENT_FUNCTION,
623 OOMPH_EXCEPTION_LOCATION);
624 }
625
626 // Declaration of variables
627 std::string line;
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 }
665
666
667 /// Helper function to setup the output structures
668 void setup(Mesh* mesh_pt, const Vector<Vector<double>>& coord_vec)
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
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],
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 }
799
800 // Get coordinates of found points
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 }
820
821
822 /// Vector of pairs containing points to finite elements and
823 /// local coordinates
825
826 /// Number of plot points
827 unsigned Nplot_points;
828
829 }; // end of class
830
831} // namespace oomph
832
833#endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
double & max_search_radius()
Set maximum search radius for locate zeta. This is initialised do DBL_MAX so we brutally search throu...
A general Finite Element class.
Definition: elements.h:1313
/////////////////////////////////////////////////////////////////////
Definition: geom_objects.h:101
Class to aid visualisation of the values on a set of points. NOTE: in a distributed problem,...
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.
LineVisualiser(Mesh *mesh_pt, const std::string file_name, const double &scale=1.0)
Constructor reading centerline file.
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...
unsigned Nplot_points
Number of plot points.
void update_plot_points_coordinates(Vector< Vector< double > > &coord_vec)
Update plot points coordinates (in preparation of remesh, say).
void setup(Mesh *mesh_pt, const Vector< Vector< double > > &coord_vec)
Helper function to setup the output structures.
void get_local_plot_points_coordinates(Vector< Vector< double > > &data)
LineVisualiser(Mesh *mesh_pt, const double &max_search_radius, const std::string file_name, const double &scale=1.0)
Constructor reading centerline file.
double Max_search_radius
Max radius beyond which we stop searching the bin. Initialised to DBL_MAX so keep going until the poi...
void output(std::ostream &outfile)
Output function: output each plot point. NOTE: in a distributed problem, output is only done on proce...
void setup_from_file(Mesh *mesh_pt, const std::string file_name, const double &scale)
Helper function to setup from file.
void get_output_data(Vector< Vector< double > > &data)
Output data function: store data associated with each plot point in data array.
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
SamplePointContainer * sample_point_container_pt() const
Pointer to the sample point container.
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...
A general mesh class.
Definition: mesh.h:67
An oomph-lib wrapper to the MPI_Comm communicator object. Just contains an MPI_Comm object (which is ...
Definition: communicator.h:54
An OomphLibError object which should be thrown when an run-time error is encountered....
A slight extension to the standard template vector class so that we can include "graceful" array rang...
Definition: Vector.h:58
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
double timer()
returns the time in seconds after some point in past
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...