libMesh
tecplot_io.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 #include <fstream>
22 #include <iomanip>
23 #include <sstream>
24 
25 // Local includes
26 #include "libmesh/libmesh_config.h"
27 #include "libmesh/libmesh_logging.h"
28 #include "libmesh/tecplot_io.h"
29 #include "libmesh/mesh_base.h"
30 #include "libmesh/elem.h"
31 #include "libmesh/parallel.h"
32 
33 #ifdef LIBMESH_HAVE_TECPLOT_API
34 extern "C" {
35 # include <TECIO.h>
36 }
37 #endif
38 
39 
40 namespace libMesh
41 {
42 
43 
44 //--------------------------------------------------------
45 // Macros for handling Tecplot API data
46 
47 #ifdef LIBMESH_HAVE_TECPLOT_API
48 
49 namespace
50 {
51 class TecplotMacros
52 {
53 public:
54  TecplotMacros(const dof_id_type n_nodes,
55  const unsigned int n_vars,
56  const dof_id_type n_cells,
57  const unsigned int n_vert);
58  float & nd(const std::size_t i, const std::size_t j);
59  int & cd(const std::size_t i, const std::size_t j);
60  std::vector<float> nodalData;
61  std::vector<int> connData;
62  //float* nodalData;
63  //int * connData;
64 
65  void set_n_cells (const dof_id_type nc);
66 
68  const unsigned int n_vars;
70  const unsigned int n_vert;
71 };
72 }
73 
74 
75 
76 inline
77 TecplotMacros::TecplotMacros(const dof_id_type nn,
78  const unsigned int nvar,
79  const dof_id_type nc,
80  const unsigned int nvrt) :
81  n_nodes(nn),
82  n_vars(nvar),
83  n_cells(nc),
84  n_vert(nvrt)
85 {
86  nodalData.resize(n_nodes*n_vars);
87  connData.resize(n_cells*n_vert);
88 }
89 
90 
91 
92 inline
93 float & TecplotMacros::nd(const std::size_t i, const std::size_t j)
94 {
95  return nodalData[(i)*(n_nodes) + (j)];
96 }
97 
98 
99 
100 inline
101 int & TecplotMacros::cd(const std::size_t i, const std::size_t j)
102 {
103  return connData[(i) + (j)*(n_vert)];
104 }
105 
106 
107 inline
108 void TecplotMacros::set_n_cells (const dof_id_type nc)
109 {
110  n_cells = nc;
111  connData.resize(n_cells*n_vert);
112 }
113 #endif
114 //--------------------------------------------------------
115 
116 
117 
118 // ------------------------------------------------------------
119 // TecplotIO members
120 TecplotIO::TecplotIO (const MeshBase & mesh_in,
121  const bool binary_in,
122  const double time_in,
123  const int strand_offset_in) :
124  MeshOutput<MeshBase> (mesh_in),
125  _binary (binary_in),
126  _time (time_in),
127  _strand_offset (strand_offset_in),
128  _zone_title ("zone"),
129  _ascii_append(false)
130 {
131  // Gather a list of subdomain ids in the mesh.
132  // We must do this now, while we have every
133  // processor's attention
134  // (some of the write methods only execute on processor 0).
135  mesh_in.subdomain_ids (_subdomain_ids);
136 }
137 
138 
139 
141 {
142  return _binary;
143 }
144 
145 
146 
147 double & TecplotIO::time ()
148 {
149  return _time;
150 }
151 
152 
153 
155 {
156  return _strand_offset;
157 }
158 
159 
160 
161 std::string & TecplotIO::zone_title ()
162 {
163  return _zone_title;
164 }
165 
166 
168 {
169  return _ascii_append;
170 }
171 
172 
173 void TecplotIO::write (const std::string & fname)
174 {
175  if (this->mesh().processor_id() == 0)
176  {
177  if (this->binary())
178  this->write_binary (fname);
179  else
180  this->write_ascii (fname);
181  }
182 }
183 
184 
185 
186 void TecplotIO::write_nodal_data (const std::string & fname,
187  const std::vector<Number> & soln,
188  const std::vector<std::string> & names)
189 {
190  LOG_SCOPE("write_nodal_data()", "TecplotIO");
191 
192  if (this->mesh().processor_id() == 0)
193  {
194  if (this->binary())
195  this->write_binary (fname, &soln, &names);
196  else
197  this->write_ascii (fname, &soln, &names);
198  }
199 }
200 
201 
202 
204 {
205  // Get a constant reference to the mesh.
206  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();
207 
208  std::vector<unsigned> elem_dims(3);
209 
210  // Loop over all the elements and mark the proper dimension entry in
211  // the elem_dims vector.
212  for (const auto & elem : the_mesh.active_element_ptr_range())
213  elem_dims[elem->dim() - 1] = 1;
214 
215  // Detect and disallow (for now) the writing of mixed dimension meshes.
216  if (std::count(elem_dims.begin(), elem_dims.end(), 1) > 1)
217  libmesh_error_msg("Error, cannot write Mesh with mixed element dimensions to Tecplot file!");
218 
219  if (elem_dims[0])
220  return 1;
221  else if (elem_dims[1])
222  return 2;
223  else if (elem_dims[2])
224  return 3;
225  else
226  libmesh_error_msg("No 1, 2, or 3D elements detected!");
227 }
228 
229 
230 
231 void TecplotIO::write_ascii (const std::string & fname,
232  const std::vector<Number> * v,
233  const std::vector<std::string> * solution_names)
234 {
235  // Should only do this on processor 0!
236  libmesh_assert_equal_to (this->mesh().processor_id(), 0);
237 
238  // Create an output stream, possibly in append mode.
239  std::ofstream out_stream(fname.c_str(), _ascii_append ? std::ofstream::app : std::ofstream::out);
240 
241  // Make sure it opened correctly
242  if (!out_stream.good())
243  libmesh_file_error(fname.c_str());
244 
245  // Get a constant reference to the mesh.
246  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();
247 
248  // Write header to stream
249  {
250  {
251  // TODO: We used to print out the SVN revision here when we did keyword expansions...
252  out_stream << "# For a description of the Tecplot format see the Tecplot User's guide.\n"
253  << "#\n";
254  }
255 
256  out_stream << "Variables=x,y,z";
257 
258  if (solution_names != libmesh_nullptr)
259  for (std::size_t n=0; n<solution_names->size(); n++)
260  {
261 #ifdef LIBMESH_USE_REAL_NUMBERS
262 
263  // Write variable names for real variables
264  out_stream << "," << (*solution_names)[n];
265 
266 #else
267 
268  // Write variable names for complex variables
269  out_stream << "," << "r_" << (*solution_names)[n]
270  << "," << "i_" << (*solution_names)[n]
271  << "," << "a_" << (*solution_names)[n];
272 
273 #endif
274  }
275 
276  out_stream << '\n';
277 
278  out_stream << "Zone f=fepoint, n=" << the_mesh.n_nodes() << ", e=" << the_mesh.n_active_sub_elem();
279 
280  // We cannot choose the element type simply based on the mesh
281  // dimension... there might be 1D elements living in a 3D mesh.
282  // So look at the elements which are actually in the Mesh, and
283  // choose either "lineseg", "quadrilateral", or "brick" depending
284  // on if the elements are 1, 2, or 3D.
285 
286  // Write the element type we've determined to the header.
287  out_stream << ", et=";
288 
289  switch (this->elem_dimension())
290  {
291  case 1:
292  out_stream << "lineseg";
293  break;
294  case 2:
295  out_stream << "quadrilateral";
296  break;
297  case 3:
298  out_stream << "brick";
299  break;
300  default:
301  libmesh_error_msg("Unsupported element dimension: " << this->elem_dimension());
302  }
303 
304  // Output the time in the header
305  out_stream << ", t=\"T " << _time << "\"";
306 
307  // Use default mesh color = black
308  out_stream << ", c=black\n";
309 
310  } // finished writing header
311 
312  for (unsigned int i=0; i<the_mesh.n_nodes(); i++)
313  {
314  // Print the point without a newline
315  the_mesh.point(i).write_unformatted(out_stream, false);
316 
317  if ((v != libmesh_nullptr) && (solution_names != libmesh_nullptr))
318  {
319  const std::size_t n_vars = solution_names->size();
320 
321 
322  for (std::size_t c=0; c<n_vars; c++)
323  {
324 #ifdef LIBMESH_USE_REAL_NUMBERS
325  // Write real data
326  out_stream << std::setprecision(this->ascii_precision())
327  << (*v)[i*n_vars + c] << " ";
328 
329 #else
330  // Write complex data
331  out_stream << std::setprecision(this->ascii_precision())
332  << (*v)[i*n_vars + c].real() << " "
333  << (*v)[i*n_vars + c].imag() << " "
334  << std::abs((*v)[i*n_vars + c]) << " ";
335 
336 #endif
337  }
338  }
339 
340  // Write a new line after the data for this node
341  out_stream << '\n';
342  }
343 
344  for (const auto & elem : the_mesh.active_element_ptr_range())
345  elem->write_connectivity(out_stream, TECPLOT);
346 }
347 
348 
349 
350 void TecplotIO::write_binary (const std::string & fname,
351  const std::vector<Number> * vec,
352  const std::vector<std::string> * solution_names)
353 {
354  //-----------------------------------------------------------
355  // Call the ASCII output function if configure did not detect
356  // the Tecplot binary API
357 #ifndef LIBMESH_HAVE_TECPLOT_API
358 
359  libMesh::err << "WARNING: Tecplot Binary files require the Tecplot API." << std::endl
360  << "Continuing with ASCII output."
361  << std::endl;
362 
363  if (this->mesh().processor_id() == 0)
364  this->write_ascii (fname, vec, solution_names);
365  return;
366 
367 
368 
369  //------------------------------------------------------------
370  // New binary formats, time aware and whatnot
371 #elif defined(LIBMESH_HAVE_TECPLOT_API_112)
372 
373  // Get a constant reference to the mesh.
374  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();
375 
376  // Required variables
377  std::string tecplot_variable_names;
378  int
379  ierr = 0,
380  file_type = 0, // full
381  is_double = 0,
382 #ifdef DEBUG
383  tec_debug = 1,
384 #else
385  tec_debug = 0,
386 #endif
387  cell_type = -1,
388  nn_per_elem = -1;
389 
390  switch (this->elem_dimension())
391  {
392  case 1:
393  cell_type = 1; // FELINESEG
394  nn_per_elem = 2;
395  break;
396 
397  case 2:
398  cell_type = 3; // FEQUADRILATERAL
399  nn_per_elem = 4;
400  break;
401 
402  case 3:
403  cell_type = 5; // FEBRICK
404  nn_per_elem = 8;
405  break;
406 
407  default:
408  libmesh_error_msg("Unsupported element dimension: " << this->elem_dimension());
409  }
410 
411  // Build a string containing all the variable names to pass to Tecplot
412  {
413  tecplot_variable_names += "x, y, z";
414 
415  if (solution_names != libmesh_nullptr)
416  {
417  for (std::size_t name=0; name<solution_names->size(); name++)
418  {
419 #ifdef LIBMESH_USE_REAL_NUMBERS
420 
421  tecplot_variable_names += ", ";
422  tecplot_variable_names += (*solution_names)[name];
423 
424 #else
425 
426  tecplot_variable_names += ", ";
427  tecplot_variable_names += "r_";
428  tecplot_variable_names += (*solution_names)[name];
429  tecplot_variable_names += ", ";
430  tecplot_variable_names += "i_";
431  tecplot_variable_names += (*solution_names)[name];
432  tecplot_variable_names += ", ";
433  tecplot_variable_names += "a_";
434  tecplot_variable_names += (*solution_names)[name];
435 
436 #endif
437  }
438  }
439  }
440 
441  // Instantiate a TecplotMacros interface. In 2D the most nodes per
442  // face should be 4, in 3D it's 8.
443 
444 
445  TecplotMacros tm(the_mesh.n_nodes(),
446 #ifdef LIBMESH_USE_REAL_NUMBERS
447  (3 + ((solution_names == libmesh_nullptr) ? 0 :
448  cast_int<unsigned int>(solution_names->size()))),
449 #else
450  (3 + 3*((solution_names == libmesh_nullptr) ? 0 :
451  cast_int<unsigned int>(solution_names->size()))),
452 #endif
453  the_mesh.n_active_sub_elem(),
454  nn_per_elem
455  );
456 
457 
458  // Copy the nodes and data to the TecplotMacros class. Note that we store
459  // everything as a float here since the eye doesn't require a double to
460  // understand what is going on
461  for (unsigned int v=0; v<the_mesh.n_nodes(); v++)
462  {
463  tm.nd(0,v) = static_cast<float>(the_mesh.point(v)(0));
464  tm.nd(1,v) = static_cast<float>(the_mesh.point(v)(1));
465  tm.nd(2,v) = static_cast<float>(the_mesh.point(v)(2));
466 
467  if ((vec != libmesh_nullptr) &&
468  (solution_names != libmesh_nullptr))
469  {
470  const std::size_t n_vars = solution_names->size();
471 
472  for (std::size_t c=0; c<n_vars; c++)
473  {
474 #ifdef LIBMESH_USE_REAL_NUMBERS
475 
476  tm.nd((3+c),v) = static_cast<float>((*vec)[v*n_vars + c]);
477 #else
478  tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*n_vars + c].real());
479  tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*n_vars + c].imag());
480  tm.nd((3+3*c+2),v) = static_cast<float>(std::abs((*vec)[v*n_vars + c]));
481 #endif
482  }
483  }
484  }
485 
486 
487  // Initialize the file
488  ierr = TECINI112 (libmesh_nullptr,
489  const_cast<char *>(tecplot_variable_names.c_str()),
490  const_cast<char *>(fname.c_str()),
491  const_cast<char *>("."),
492  &file_type,
493  &tec_debug,
494  &is_double);
495 
496  if (ierr)
497  libmesh_file_error(fname);
498 
499  // A zone for each subdomain
500  bool firstzone=true;
501  for (std::set<subdomain_id_type>::const_iterator sbd_it=_subdomain_ids.begin();
502  sbd_it!=_subdomain_ids.end(); ++sbd_it)
503  {
504  // Copy the connectivity for this subdomain
505  {
508 
509  unsigned int n_subcells_in_subdomain=0;
510 
511  for (; it != end; ++it)
512  n_subcells_in_subdomain += (*it)->n_sub_elem();
513 
514  // update the connectivity array to include only the elements in this subdomain
515  tm.set_n_cells (n_subcells_in_subdomain);
516 
517  unsigned int te = 0;
518 
519  for (it = the_mesh.active_subdomain_elements_begin (*sbd_it);
520  it != end; ++it)
521  {
522  std::vector<dof_id_type> conn;
523  for (unsigned int se=0; se<(*it)->n_sub_elem(); se++)
524  {
525  (*it)->connectivity(se, TECPLOT, conn);
526 
527  for (std::size_t node=0; node<conn.size(); node++)
528  tm.cd(node,te) = conn[node];
529 
530  te++;
531  }
532  }
533  }
534 
535 
536  // Ready to call the Tecplot API for this subdomain
537  {
538  int
539  num_nodes = static_cast<int>(the_mesh.n_nodes()),
540  num_cells = static_cast<int>(tm.n_cells),
541  num_faces = 0,
542  i_cell_max = 0,
543  j_cell_max = 0,
544  k_cell_max = 0,
545  strand_id = std::max(*sbd_it,static_cast<subdomain_id_type>(1)) + this->strand_offset(),
546  parent_zone = 0,
547  is_block = 1,
548  num_face_connect = 0,
549  face_neighbor_mode = 0,
550  tot_num_face_nodes = 0,
551  num_connect_boundary_faces = 0,
552  tot_num_boundary_connect = 0,
553  share_connect_from_zone=0;
554 
555  std::vector<int>
556  passive_var_list (tm.n_vars, 0),
557  share_var_from_zone (tm.n_vars, 1); // We only write data for the first zone, all other
558  // zones will share from this one.
559 
560  // get the subdomain name from libMesh, if there is one.
561  std::string subdomain_name = the_mesh.subdomain_name(*sbd_it);
562  std::ostringstream zone_name;
563  zone_name << this->zone_title();
564 
565  // We will title this
566  // "{zone_title()}_{subdomain_name}", or
567  // "{zone_title()}_{subdomain_id}", or
568  // "{zone_title()}"
569  if (subdomain_name.size())
570  {
571  zone_name << "_";
572  zone_name << subdomain_name;
573  }
574  else if (_subdomain_ids.size() > 1)
575  {
576  zone_name << "_";
577  zone_name << *sbd_it;
578  }
579 
580  ierr = TECZNE112 (const_cast<char *>(zone_name.str().c_str()),
581  &cell_type,
582  &num_nodes,
583  &num_cells,
584  &num_faces,
585  &i_cell_max,
586  &j_cell_max,
587  &k_cell_max,
588  &_time,
589  &strand_id,
590  &parent_zone,
591  &is_block,
592  &num_face_connect,
593  &face_neighbor_mode,
594  &tot_num_face_nodes,
595  &num_connect_boundary_faces,
596  &tot_num_boundary_connect,
597  &passive_var_list[0],
598  libmesh_nullptr, // = all are node centered
599  (firstzone) ? libmesh_nullptr : &share_var_from_zone[0],
600  &share_connect_from_zone);
601 
602  if (ierr)
603  libmesh_file_error(fname);
604 
605  // Write *all* the data for the first zone, then share it with the others
606  if (firstzone)
607  {
608  int total = cast_int<int>
609 #ifdef LIBMESH_USE_REAL_NUMBERS
610  ((3 + ((solution_names == libmesh_nullptr) ? 0 : solution_names->size()))*num_nodes);
611 #else
612  ((3 + 3*((solution_names == libmesh_nullptr) ? 0 : solution_names->size()))*num_nodes);
613 #endif
614 
615 
616  ierr = TECDAT112 (&total,
617  &tm.nodalData[0],
618  &is_double);
619 
620  if (ierr)
621  libmesh_file_error(fname);
622  }
623 
624  // Write the connectivity
625  ierr = TECNOD112 (&tm.connData[0]);
626 
627  if (ierr)
628  libmesh_file_error(fname);
629  }
630 
631  firstzone = false;
632  }
633 
634  // Done, close the file.
635  ierr = TECEND112 ();
636 
637  if (ierr)
638  libmesh_file_error(fname);
639 
640 
641 
642 
643  //------------------------------------------------------------
644  // Legacy binary format
645 #else
646 
647  // Get a constant reference to the mesh.
648  const MeshBase & the_mesh = MeshOutput<MeshBase>::mesh();
649 
650  // Tecplot binary output only good for dim=2,3
651  if (the_mesh.mesh_dimension() == 1)
652  {
653  this->write_ascii (fname, vec, solution_names);
654 
655  return;
656  }
657 
658  // Required variables
659  std::string tecplot_variable_names;
660  int is_double = 0,
661  tec_debug = 0,
662  cell_type = ((the_mesh.mesh_dimension()==2) ? (1) : (3));
663 
664  // Build a string containing all the variable names to pass to Tecplot
665  {
666  tecplot_variable_names += "x, y, z";
667 
668  if (solution_names != libmesh_nullptr)
669  {
670  for (std::size_t name=0; name<solution_names->size(); name++)
671  {
672 #ifdef LIBMESH_USE_REAL_NUMBERS
673 
674  tecplot_variable_names += ", ";
675  tecplot_variable_names += (*solution_names)[name];
676 
677 #else
678 
679  tecplot_variable_names += ", ";
680  tecplot_variable_names += "r_";
681  tecplot_variable_names += (*solution_names)[name];
682  tecplot_variable_names += ", ";
683  tecplot_variable_names += "i_";
684  tecplot_variable_names += (*solution_names)[name];
685  tecplot_variable_names += ", ";
686  tecplot_variable_names += "a_";
687  tecplot_variable_names += (*solution_names)[name];
688 
689 #endif
690  }
691  }
692  }
693 
694  // Instantiate a TecplotMacros interface. In 2D the most nodes per
695  // face should be 4, in 3D it's 8.
696 
697 
698  TecplotMacros tm(cast_int<unsigned int>(the_mesh.n_nodes()),
699  cast_int<unsigned int>
700 #ifdef LIBMESH_USE_REAL_NUMBERS
701  (3 + ((solution_names == libmesh_nullptr) ? 0 : solution_names->size())),
702 #else
703  (3 + 3*((solution_names == libmesh_nullptr) ? 0 : solution_names->size())),
704 #endif
705  cast_int<unsigned int>
706  (the_mesh.n_active_sub_elem()),
707  ((the_mesh.mesh_dimension() == 2) ? 4 : 8)
708  );
709 
710 
711  // Copy the nodes and data to the TecplotMacros class. Note that we store
712  // everything as a float here since the eye doesn't require a double to
713  // understand what is going on
714  for (unsigned int v=0; v<the_mesh.n_nodes(); v++)
715  {
716  tm.nd(0,v) = static_cast<float>(the_mesh.point(v)(0));
717  tm.nd(1,v) = static_cast<float>(the_mesh.point(v)(1));
718  tm.nd(2,v) = static_cast<float>(the_mesh.point(v)(2));
719 
720  if ((vec != libmesh_nullptr) &&
721  (solution_names != libmesh_nullptr))
722  {
723  const std::size_t n_vars = solution_names->size();
724 
725  for (std::size_t c=0; c<n_vars; c++)
726  {
727 #ifdef LIBMESH_USE_REAL_NUMBERS
728 
729  tm.nd((3+c),v) = static_cast<float>((*vec)[v*n_vars + c]);
730 #else
731  tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*n_vars + c].real());
732  tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*n_vars + c].imag());
733  tm.nd((3+3*c+2),v) = static_cast<float>(std::abs((*vec)[v*n_vars + c]));
734 #endif
735  }
736  }
737  }
738 
739 
740  // Copy the connectivity
741  {
742  unsigned int te = 0;
743 
744  for (const auto & elem : the_mesh.active_element_ptr_range())
745  {
746  std::vector<dof_id_type> conn;
747  for (unsigned int se=0; se<elem->n_sub_elem(); se++)
748  {
749  elem->connectivity(se, TECPLOT, conn);
750 
751  for (std::size_t node=0; node<conn.size(); node++)
752  tm.cd(node,te) = conn[node];
753 
754  te++;
755  }
756  }
757  }
758 
759 
760  // Ready to call the Tecplot API
761  {
762  int ierr = 0,
763  num_nodes = static_cast<int>(the_mesh.n_nodes()),
764  num_cells = static_cast<int>(the_mesh.n_active_sub_elem());
765 
766 
767  ierr = TECINI (libmesh_nullptr,
768  (char *) tecplot_variable_names.c_str(),
769  (char *) fname.c_str(),
770  (char *) ".",
771  &tec_debug,
772  &is_double);
773 
774  if (ierr)
775  libmesh_file_error(fname);
776 
777 
778  ierr = TECZNE (libmesh_nullptr,
779  &num_nodes,
780  &num_cells,
781  &cell_type,
782  (char *) "FEBLOCK",
784 
785  if (ierr)
786  libmesh_file_error(fname);
787 
788 
789  int total =
790 #ifdef LIBMESH_USE_REAL_NUMBERS
791  ((3 + ((solution_names == libmesh_nullptr) ? 0 : solution_names->size()))*num_nodes);
792 #else
793  ((3 + 3*((solution_names == libmesh_nullptr) ? 0 : solution_names->size()))*num_nodes);
794 #endif
795 
796 
797  ierr = TECDAT (&total,
798  &tm.nodalData[0],
799  &is_double);
800 
801  if (ierr)
802  libmesh_file_error(fname);
803 
804  ierr = TECNOD (&tm.connData[0]);
805 
806  if (ierr)
807  libmesh_file_error(fname);
808 
809  ierr = TECEND ();
810 
811  if (ierr)
812  libmesh_file_error(fname);
813  }
814 
815 #endif
816 }
817 
818 } // namespace libMesh
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:39
dof_id_type n_active_sub_elem() const
Same as n_sub_elem(), but only counts active elements.
Definition: mesh_base.C:399
OStreamProxy err
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) libmesh_override
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: tecplot_io.C:186
double abs(double a)
int & strand_offset()
Strand offset for this file.
Definition: tecplot_io.C:154
double _time
Solution time.
Definition: tecplot_io.h:151
std::vector< int > connData
Definition: tecplot_io.C:61
virtual const Point & point(const dof_id_type i) const =0
void write_binary(const std::string &, const std::vector< Number > *=libmesh_nullptr, const std::vector< std::string > *=libmesh_nullptr)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: tecplot_io.C:350
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1494
virtual element_iterator active_subdomain_elements_end(subdomain_id_type subdomain_id)=0
void write_unformatted(std::ostream &out, const bool newline=true) const
Unformatted print to the stream out.
Definition: type_vector.C:92
const class libmesh_nullptr_t libmesh_nullptr
unsigned int & ascii_precision()
Return/set the precision to use when writing ASCII files.
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
const MeshBase & mesh() const
This class defines an abstract interface for Mesh output.
Definition: mesh_output.h:53
const unsigned int n_vars
Definition: tecplot_io.C:68
The libMesh namespace provides an interface to certain functionality in the library.
long double max(long double a, double b)
bool & binary()
Flag indicating whether or not to write a binary file (if the tecio.a library was found by configure)...
Definition: tecplot_io.C:140
This is the MeshBase class.
Definition: mesh_base.h:68
bool _binary
Flag to write binary data.
Definition: tecplot_io.h:146
std::set< subdomain_id_type > _subdomain_ids
The subdomains in the mesh.
Definition: tecplot_io.h:172
virtual element_iterator active_subdomain_elements_begin(subdomain_id_type subdomain_id)=0
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void subdomain_ids(std::set< subdomain_id_type > &ids) const
Constructs a list of all subdomain identifiers in the global mesh.
Definition: mesh_base.C:315
virtual void write(const std::string &) libmesh_override
This method implements writing a mesh to a specified file.
Definition: tecplot_io.C:173
int _strand_offset
Offset for Tecplot&#39;s STRANDID.
Definition: tecplot_io.h:156
std::string & subdomain_name(subdomain_id_type id)
Definition: mesh_base.C:576
void write_ascii(const std::string &, const std::vector< Number > *=libmesh_nullptr, const std::vector< std::string > *=libmesh_nullptr)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: tecplot_io.C:231
unsigned elem_dimension()
Determines the logical spatial dimension of the elements in the Mesh.
Definition: tecplot_io.C:203
PetscErrorCode ierr
OStreamProxy out
unsigned int mesh_dimension() const
Definition: mesh_base.C:148
bool _ascii_append
If true, when writing in ASCII format, open the file in std::ofstream::app mode.
Definition: tecplot_io.h:167
dof_id_type n_cells
Definition: tecplot_io.C:69
virtual dof_id_type n_nodes() const =0
processor_id_type processor_id()
Definition: libmesh_base.h:96
const unsigned int n_vert
Definition: tecplot_io.C:70
std::vector< float > nodalData
Definition: tecplot_io.C:60
bool & ascii_append()
Set to true to write multiple solutions to a single file (ASCII only).
Definition: tecplot_io.C:167
std::string & zone_title()
The zone title to write.
Definition: tecplot_io.C:161
std::string _zone_title
The zone title to write.
Definition: tecplot_io.h:161
uint8_t dof_id_type
Definition: id_types.h:64
double & time()
Solution time for transient data.
Definition: tecplot_io.C:147