21 #include "libmesh/libmesh_config.h" 22 #include "libmesh/libmesh_logging.h" 23 #include "libmesh/tecplot_io.h" 24 #include "libmesh/mesh_base.h" 25 #include "libmesh/elem.h" 26 #include "libmesh/enum_io_package.h" 27 #include "libmesh/int_range.h" 29 #ifdef LIBMESH_HAVE_TECPLOT_API 47 #ifdef LIBMESH_HAVE_TECPLOT_API 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);
77 const unsigned int nvar,
79 const unsigned int nvrt) :
92 float & TecplotMacros::nd(
const std::size_t i,
const std::size_t j)
100 int & TecplotMacros::cd(
const std::size_t i,
const std::size_t j)
107 void TecplotMacros::set_n_cells (
const dof_id_type nc)
122 const bool binary_in,
123 const double time_in,
124 const int strand_offset_in) :
128 _strand_offset (strand_offset_in),
129 _zone_title (
"zone"),
176 if (this->
mesh().processor_id() == 0)
188 const std::vector<Number> & soln,
189 const std::vector<std::string> & names)
191 LOG_SCOPE(
"write_nodal_data()",
"TecplotIO");
193 if (this->
mesh().processor_id() == 0)
209 std::vector<unsigned> elem_dims(3);
213 for (
const auto & elem : the_mesh.active_element_ptr_range())
214 elem_dims[elem->dim() - 1] = 1;
217 libmesh_error_msg_if(std::count(elem_dims.begin(), elem_dims.end(), 1) > 1,
218 "Error, cannot write Mesh with mixed element dimensions to Tecplot file!");
222 else if (elem_dims[1])
224 else if (elem_dims[2])
227 libmesh_error_msg(
"No 1, 2, or 3D elements detected!");
233 const std::vector<Number> * v,
234 const std::vector<std::string> * solution_names)
237 libmesh_assert_equal_to (this->
mesh().processor_id(), 0);
243 if (!out_stream.good())
244 libmesh_file_error(fname.c_str());
253 out_stream <<
"# For a description of the Tecplot format see the Tecplot User's guide.\n" 257 out_stream <<
"Variables=x,y,z";
259 if (solution_names !=
nullptr)
260 for (
const auto & val : *solution_names)
262 #ifdef LIBMESH_USE_REAL_NUMBERS 265 out_stream <<
"," << val;
270 out_stream <<
"," <<
"r_" << val
271 <<
"," <<
"i_" << val
272 <<
"," <<
"a_" << val;
288 out_stream <<
", et=";
293 out_stream <<
"lineseg";
296 out_stream <<
"quadrilateral";
299 out_stream <<
"brick";
302 libmesh_error_msg(
"Unsupported element dimension: " << this->
elem_dimension());
306 out_stream <<
", t=\"T " <<
_time <<
"\"";
309 out_stream <<
", c=black\n";
318 if ((v !=
nullptr) && (solution_names !=
nullptr))
320 const std::size_t
n_vars = solution_names->size();
323 for (std::size_t c=0; c<
n_vars; c++)
325 #ifdef LIBMESH_USE_REAL_NUMBERS 328 << (*v)[i*
n_vars + c] <<
" ";
333 << (*v)[i*
n_vars + c].real() <<
" " 334 << (*v)[i*
n_vars + c].imag() <<
" " 335 << std::abs((*v)[i*
n_vars + c]) <<
" ";
345 for (
const auto & elem : the_mesh.active_element_ptr_range())
346 elem->write_connectivity(out_stream,
TECPLOT);
352 const std::vector<Number> * vec,
353 const std::vector<std::string> * solution_names)
358 #ifndef LIBMESH_HAVE_TECPLOT_API 360 libMesh::err <<
"WARNING: Tecplot Binary files require the Tecplot API." << std::endl
361 <<
"Continuing with ASCII output." 364 if (this->
mesh().processor_id() == 0)
372 #elif defined(LIBMESH_HAVE_TECPLOT_API_112) 378 std::string tecplot_variable_names;
409 libmesh_error_msg(
"Unsupported element dimension: " << this->
elem_dimension());
414 tecplot_variable_names +=
"x, y, z";
416 if (solution_names !=
nullptr)
418 for (
const auto & val : *solution_names)
420 #ifdef LIBMESH_USE_REAL_NUMBERS 422 tecplot_variable_names +=
", ";
423 tecplot_variable_names += val;
427 tecplot_variable_names +=
", ";
428 tecplot_variable_names +=
"r_";
429 tecplot_variable_names += val;
430 tecplot_variable_names +=
", ";
431 tecplot_variable_names +=
"i_";
432 tecplot_variable_names += val;
433 tecplot_variable_names +=
", ";
434 tecplot_variable_names +=
"a_";
435 tecplot_variable_names += val;
446 TecplotMacros tm(the_mesh.
n_nodes(),
447 #ifdef LIBMESH_USE_REAL_NUMBERS 448 (3 + ((solution_names ==
nullptr) ? 0 :
449 cast_int<unsigned int>(solution_names->size()))),
451 (3 + 3*((solution_names ==
nullptr) ? 0 :
452 cast_int<unsigned int>(solution_names->size()))),
464 tm.nd(0,v) =
static_cast<float>(the_mesh.
point(v)(0));
465 tm.nd(1,v) =
static_cast<float>(the_mesh.
point(v)(1));
466 tm.nd(2,v) =
static_cast<float>(the_mesh.
point(v)(2));
468 if ((vec !=
nullptr) &&
469 (solution_names !=
nullptr))
471 const std::size_t
n_vars = solution_names->size();
473 for (std::size_t c=0; c<
n_vars; c++)
475 #ifdef LIBMESH_USE_REAL_NUMBERS 477 tm.nd((3+c),v) =
static_cast<float>((*vec)[v*
n_vars + c]);
479 tm.nd((3+3*c),v) =
static_cast<float>((*vec)[v*
n_vars + c].real());
480 tm.nd((3+3*c+1),v) =
static_cast<float>((*vec)[v*
n_vars + c].imag());
481 tm.nd((3+3*c+2),v) =
static_cast<float>(std::abs((*vec)[v*
n_vars + c]));
489 ierr = TECINI112 (
nullptr,
490 const_cast<char *>(tecplot_variable_names.c_str()),
491 const_cast<char *>(fname.c_str()),
492 const_cast<char *>(
"."),
498 libmesh_file_error(fname);
506 unsigned int n_subcells_in_subdomain=0;
508 for (
const auto & elem :
509 as_range(the_mesh.active_subdomain_elements_begin(sbd_id),
510 the_mesh.active_subdomain_elements_end(sbd_id)))
511 n_subcells_in_subdomain += elem->n_sub_elem();
514 tm.set_n_cells (n_subcells_in_subdomain);
518 for (
const auto & elem :
519 as_range(the_mesh.active_subdomain_elements_begin(sbd_id),
520 the_mesh.active_subdomain_elements_end(sbd_id)))
522 std::vector<dof_id_type> conn;
523 for (
auto se :
make_range(elem->n_sub_elem()))
525 elem->connectivity(se,
TECPLOT, conn);
528 tm.cd(node,te) = conn[node];
539 num_nodes =
static_cast<int>(the_mesh.
n_nodes()),
540 num_cells = static_cast<int>(tm.n_cells),
545 strand_id = std::max(sbd_id, static_cast<subdomain_id_type>(1)) + this->
strand_offset(),
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;
556 passive_var_list (tm.n_vars, 0),
557 share_var_from_zone (tm.n_vars, 1);
562 std::ostringstream zone_name;
569 if (subdomain_name.size())
572 zone_name << subdomain_name;
580 ierr = TECZNE112 (const_cast<char *>(zone_name.str().c_str()),
595 &num_connect_boundary_faces,
596 &tot_num_boundary_connect,
597 passive_var_list.data(),
599 (firstzone) ?
nullptr : share_var_from_zone.data(),
600 &share_connect_from_zone);
603 libmesh_file_error(fname);
608 int total = cast_int<int>
609 #ifdef LIBMESH_USE_REAL_NUMBERS 610 ((3 + ((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
612 ((3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
616 ierr = TECDAT112 (&total,
621 libmesh_file_error(fname);
625 ierr = TECNOD112 (tm.connData.data());
628 libmesh_file_error(fname);
638 libmesh_file_error(fname);
659 std::string tecplot_variable_names;
666 tecplot_variable_names +=
"x, y, z";
668 if (solution_names !=
nullptr)
670 for (
const auto & val : *solution_names)
672 #ifdef LIBMESH_USE_REAL_NUMBERS 674 tecplot_variable_names +=
", ";
675 tecplot_variable_names += val;
679 tecplot_variable_names +=
", ";
680 tecplot_variable_names +=
"r_";
681 tecplot_variable_names += val;
682 tecplot_variable_names +=
", ";
683 tecplot_variable_names +=
"i_";
684 tecplot_variable_names += val;
685 tecplot_variable_names +=
", ";
686 tecplot_variable_names +=
"a_";
687 tecplot_variable_names += val;
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 ==
nullptr) ? 0 : solution_names->size())),
703 (3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size())),
705 cast_int<unsigned int>
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));
720 if ((vec !=
nullptr) &&
721 (solution_names !=
nullptr))
723 const std::size_t
n_vars = solution_names->size();
725 for (std::size_t c=0; c<
n_vars; c++)
727 #ifdef LIBMESH_USE_REAL_NUMBERS 729 tm.nd((3+c),v) =
static_cast<float>((*vec)[v*
n_vars + c]);
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]));
744 for (
const auto & elem : the_mesh.active_element_ptr_range())
746 std::vector<dof_id_type> conn;
747 for (
auto se :
make_range(elem->n_sub_elem()))
749 elem->connectivity(se,
TECPLOT, conn);
752 tm.cd(node,te) = conn[node];
763 num_nodes =
static_cast<int>(the_mesh.
n_nodes()),
767 ierr = TECINI (
nullptr,
768 (
char *) tecplot_variable_names.c_str(),
769 (
char *) fname.c_str(),
775 libmesh_file_error(fname);
778 ierr = TECZNE (
nullptr,
786 libmesh_file_error(fname);
790 #ifdef LIBMESH_USE_REAL_NUMBERS 791 ((3 + ((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
793 ((3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
797 ierr = TECDAT (&total,
802 libmesh_file_error(fname);
804 ierr = TECNOD (tm.connData.data());
807 libmesh_file_error(fname);
812 libmesh_file_error(fname);
const MeshBase & mesh() const
int & strand_offset()
Strand offset for this file.
double _time
Solution time.
std::vector< int > connData
unsigned int & ascii_precision()
Return/set the precision to use when writing ASCII files.
This class defines an abstract interface for Mesh output.
const unsigned int n_vars
The libMesh namespace provides an interface to certain functionality in the library.
bool & binary()
Flag indicating whether or not to write a binary file (if the tecio.a library was found by configure)...
This is the MeshBase class.
bool _binary
Flag to write binary data.
std::set< subdomain_id_type > _subdomain_ids
The subdomains in the mesh.
void write_ascii(const std::string &, const std::vector< Number > *=nullptr, const std::vector< std::string > *=nullptr)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
const dof_id_type n_nodes
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
void subdomain_ids(std::set< subdomain_id_type > &ids, const bool global=true) const
Constructs a list of all subdomain identifiers in the local mesh if global == false, and in the global mesh if global == true (default).
void write_binary(const std::string &, const std::vector< Number > *=nullptr, const std::vector< std::string > *=nullptr)
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
int _strand_offset
Offset for Tecplot's STRANDID.
std::string & subdomain_name(subdomain_id_type id)
virtual void write(const std::string &) override
This method implements writing a mesh to a specified file.
unsigned elem_dimension()
Determines the logical spatial dimension of the elements in the Mesh.
bool _ascii_append
If true, when writing in ASCII format, open the file in std::ofstream::app mode.
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
dof_id_type n_active_sub_elem() const
Same as n_sub_elem(), but only counts active elements.
unsigned int mesh_dimension() const
virtual const Point & point(const dof_id_type i) const =0
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
void write_unformatted(std::ostream &out_stream, const bool newline=true) const
Unformatted print to the stream out.
const unsigned int n_vert
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
std::vector< float > nodalData
virtual dof_id_type n_nodes() const =0
bool & ascii_append()
Set to true to write multiple solutions to a single file (ASCII only).
std::string & zone_title()
The zone title to write.
std::string _zone_title
The zone title to write.
double & time()
Solution time for transient data.