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/enum_io_package.h"
32 #include "libmesh/int_range.h"
34 #ifdef LIBMESH_HAVE_TECPLOT_API
48 #ifdef LIBMESH_HAVE_TECPLOT_API
58 const unsigned int n_vert);
59 float & nd(
const std::size_t i,
const std::size_t j);
60 int & cd(
const std::size_t i,
const std::size_t j);
78 const unsigned int nvar,
80 const unsigned int nvrt) :
93 float & TecplotMacros::nd(
const std::size_t i,
const std::size_t j)
101 int & TecplotMacros::cd(
const std::size_t i,
const std::size_t j)
108 void TecplotMacros::set_n_cells (
const dof_id_type nc)
123 const bool binary_in,
124 const double time_in,
125 const int strand_offset_in) :
129 _strand_offset (strand_offset_in),
130 _zone_title (
"zone"),
177 if (this->
mesh().processor_id() == 0)
189 const std::vector<Number> & soln,
190 const std::vector<std::string> & names)
192 LOG_SCOPE(
"write_nodal_data()",
"TecplotIO");
194 if (this->
mesh().processor_id() == 0)
210 std::vector<unsigned> elem_dims(3);
215 elem_dims[elem->dim() - 1] = 1;
218 if (std::count(elem_dims.begin(), elem_dims.end(), 1) > 1)
219 libmesh_error_msg(
"Error, cannot write Mesh with mixed element dimensions to Tecplot file!");
223 else if (elem_dims[1])
225 else if (elem_dims[2])
228 libmesh_error_msg(
"No 1, 2, or 3D elements detected!");
234 const std::vector<Number> * v,
235 const std::vector<std::string> * solution_names)
238 libmesh_assert_equal_to (this->
mesh().processor_id(), 0);
244 if (!out_stream.good())
245 libmesh_file_error(fname.c_str());
254 out_stream <<
"# For a description of the Tecplot format see the Tecplot User's guide.\n"
258 out_stream <<
"Variables=x,y,z";
260 if (solution_names !=
nullptr)
261 for (
const auto & val : *solution_names)
263 #ifdef LIBMESH_USE_REAL_NUMBERS
266 out_stream <<
"," << val;
271 out_stream <<
"," <<
"r_" << val
272 <<
"," <<
"i_" << val
273 <<
"," <<
"a_" << val;
289 out_stream <<
", et=";
294 out_stream <<
"lineseg";
297 out_stream <<
"quadrilateral";
300 out_stream <<
"brick";
303 libmesh_error_msg(
"Unsupported element dimension: " << this->
elem_dimension());
307 out_stream <<
", t=\"T " <<
_time <<
"\"";
310 out_stream <<
", c=black\n";
319 if ((v !=
nullptr) && (solution_names !=
nullptr))
321 const std::size_t
n_vars = solution_names->size();
324 for (std::size_t c=0; c<
n_vars; c++)
326 #ifdef LIBMESH_USE_REAL_NUMBERS
329 << (*v)[i*
n_vars + c] <<
" ";
334 << (*v)[i*
n_vars + c].real() <<
" "
335 << (*v)[i*
n_vars + c].imag() <<
" "
347 elem->write_connectivity(out_stream,
TECPLOT);
353 const std::vector<Number> * vec,
354 const std::vector<std::string> * solution_names)
359 #ifndef LIBMESH_HAVE_TECPLOT_API
361 libMesh::err <<
"WARNING: Tecplot Binary files require the Tecplot API." << std::endl
362 <<
"Continuing with ASCII output."
365 if (this->
mesh().processor_id() == 0)
373 #elif defined(LIBMESH_HAVE_TECPLOT_API_112)
379 std::string tecplot_variable_names;
410 libmesh_error_msg(
"Unsupported element dimension: " << this->
elem_dimension());
415 tecplot_variable_names +=
"x, y, z";
417 if (solution_names !=
nullptr)
419 for (
const auto & val : *solution_names)
421 #ifdef LIBMESH_USE_REAL_NUMBERS
423 tecplot_variable_names +=
", ";
424 tecplot_variable_names += val;
428 tecplot_variable_names +=
", ";
429 tecplot_variable_names +=
"r_";
430 tecplot_variable_names += val;
431 tecplot_variable_names +=
", ";
432 tecplot_variable_names +=
"i_";
433 tecplot_variable_names += val;
434 tecplot_variable_names +=
", ";
435 tecplot_variable_names +=
"a_";
436 tecplot_variable_names += val;
447 TecplotMacros tm(the_mesh.
n_nodes(),
448 #ifdef LIBMESH_USE_REAL_NUMBERS
449 (3 + ((solution_names ==
nullptr) ? 0 :
450 cast_int<unsigned int>(solution_names->size()))),
452 (3 + 3*((solution_names ==
nullptr) ? 0 :
453 cast_int<unsigned int>(solution_names->size()))),
465 tm.nd(0,v) = static_cast<float>(the_mesh.
point(v)(0));
466 tm.nd(1,v) = static_cast<float>(the_mesh.
point(v)(1));
467 tm.nd(2,v) = static_cast<float>(the_mesh.
point(v)(2));
469 if ((vec !=
nullptr) &&
470 (solution_names !=
nullptr))
472 const std::size_t
n_vars = solution_names->size();
474 for (std::size_t c=0; c<
n_vars; c++)
476 #ifdef LIBMESH_USE_REAL_NUMBERS
478 tm.nd((3+c),v) = static_cast<float>((*vec)[v*
n_vars + c]);
480 tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*
n_vars + c].
real());
481 tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*
n_vars + c].
imag());
482 tm.nd((3+3*c+2),v) = static_cast<float>(
std::abs((*vec)[v*
n_vars + c]));
490 ierr = TECINI112 (
nullptr,
491 const_cast<char *>(tecplot_variable_names.c_str()),
492 const_cast<char *>(fname.c_str()),
493 const_cast<char *>(
"."),
499 libmesh_file_error(fname);
507 unsigned int n_subcells_in_subdomain=0;
509 for (
const auto & elem :
512 n_subcells_in_subdomain += elem->n_sub_elem();
515 tm.set_n_cells (n_subcells_in_subdomain);
519 for (
const auto & elem :
523 std::vector<dof_id_type> conn;
526 elem->connectivity(se,
TECPLOT, conn);
529 tm.cd(node,te) = conn[node];
540 num_nodes = static_cast<int>(the_mesh.
n_nodes()),
541 num_cells = static_cast<int>(tm.n_cells),
546 strand_id = std::max(sbd_id, static_cast<subdomain_id_type>(1)) + this->
strand_offset(),
549 num_face_connect = 0,
550 face_neighbor_mode = 0,
551 tot_num_face_nodes = 0,
552 num_connect_boundary_faces = 0,
553 tot_num_boundary_connect = 0,
554 share_connect_from_zone=0;
557 passive_var_list (tm.n_vars, 0),
558 share_var_from_zone (tm.n_vars, 1);
563 std::ostringstream zone_name;
570 if (subdomain_name.size())
573 zone_name << subdomain_name;
581 ierr = TECZNE112 (const_cast<char *>(zone_name.str().c_str()),
596 &num_connect_boundary_faces,
597 &tot_num_boundary_connect,
598 passive_var_list.data(),
600 (firstzone) ?
nullptr : share_var_from_zone.data(),
601 &share_connect_from_zone);
604 libmesh_file_error(fname);
609 int total = cast_int<int>
610 #ifdef LIBMESH_USE_REAL_NUMBERS
611 ((3 + ((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
613 ((3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
617 ierr = TECDAT112 (&total,
622 libmesh_file_error(fname);
626 ierr = TECNOD112 (tm.connData.data());
629 libmesh_file_error(fname);
639 libmesh_file_error(fname);
660 std::string tecplot_variable_names;
667 tecplot_variable_names +=
"x, y, z";
669 if (solution_names !=
nullptr)
671 for (
const auto & val : *solution_names)
673 #ifdef LIBMESH_USE_REAL_NUMBERS
675 tecplot_variable_names +=
", ";
676 tecplot_variable_names += val;
680 tecplot_variable_names +=
", ";
681 tecplot_variable_names +=
"r_";
682 tecplot_variable_names += val;
683 tecplot_variable_names +=
", ";
684 tecplot_variable_names +=
"i_";
685 tecplot_variable_names += val;
686 tecplot_variable_names +=
", ";
687 tecplot_variable_names +=
"a_";
688 tecplot_variable_names += val;
699 TecplotMacros tm(cast_int<unsigned int>(the_mesh.
n_nodes()),
700 cast_int<unsigned int>
701 #ifdef LIBMESH_USE_REAL_NUMBERS
702 (3 + ((solution_names ==
nullptr) ? 0 : solution_names->size())),
704 (3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size())),
706 cast_int<unsigned int>
717 tm.nd(0,v) = static_cast<float>(the_mesh.
point(v)(0));
718 tm.nd(1,v) = static_cast<float>(the_mesh.
point(v)(1));
719 tm.nd(2,v) = static_cast<float>(the_mesh.
point(v)(2));
721 if ((vec !=
nullptr) &&
722 (solution_names !=
nullptr))
724 const std::size_t
n_vars = solution_names->size();
726 for (std::size_t c=0; c<
n_vars; c++)
728 #ifdef LIBMESH_USE_REAL_NUMBERS
730 tm.nd((3+c),v) = static_cast<float>((*vec)[v*
n_vars + c]);
732 tm.nd((3+3*c),v) = static_cast<float>((*vec)[v*
n_vars + c].
real());
733 tm.nd((3+3*c+1),v) = static_cast<float>((*vec)[v*
n_vars + c].
imag());
734 tm.nd((3+3*c+2),v) = static_cast<float>(
std::abs((*vec)[v*
n_vars + c]));
747 std::vector<dof_id_type> conn;
750 elem->connectivity(se,
TECPLOT, conn);
753 tm.cd(node,te) = conn[node];
764 num_nodes = static_cast<int>(the_mesh.
n_nodes()),
768 ierr = TECINI (
nullptr,
769 (
char *) tecplot_variable_names.c_str(),
770 (
char *) fname.c_str(),
776 libmesh_file_error(fname);
779 ierr = TECZNE (
nullptr,
787 libmesh_file_error(fname);
791 #ifdef LIBMESH_USE_REAL_NUMBERS
792 ((3 + ((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
794 ((3 + 3*((solution_names ==
nullptr) ? 0 : solution_names->size()))*num_nodes);
798 ierr = TECDAT (&total,
803 libmesh_file_error(fname);
805 ierr = TECNOD (tm.connData.data());
808 libmesh_file_error(fname);
813 libmesh_file_error(fname);