23 #include "libmesh/libmesh_config.h" 
   24 #include "libmesh/vtk_io.h" 
   25 #include "libmesh/mesh_base.h" 
   26 #include "libmesh/equation_systems.h" 
   27 #include "libmesh/numeric_vector.h" 
   28 #include "libmesh/system.h" 
   29 #include "libmesh/node.h" 
   30 #include "libmesh/elem.h" 
   31 #include "libmesh/enum_io_package.h" 
   33 #ifdef LIBMESH_HAVE_VTK 
   37 #include "libmesh/ignore_warnings.h" 
   39 #include "vtkXMLUnstructuredGridReader.h" 
   40 #include "vtkXMLUnstructuredGridWriter.h" 
   41 #include "vtkXMLPUnstructuredGridWriter.h" 
   42 #include "vtkUnstructuredGrid.h" 
   43 #include "vtkIntArray.h" 
   44 #include "vtkCellArray.h" 
   45 #include "vtkCellData.h" 
   46 #include "vtkConfigure.h" 
   47 #include "vtkDoubleArray.h" 
   48 #include "vtkGenericCell.h" 
   49 #include "vtkPointData.h" 
   50 #include "vtkPoints.h" 
   51 #include "vtkSmartPointer.h" 
   53 #ifdef LIBMESH_HAVE_MPI 
   55 #include "vtkMPICommunicator.h" 
   56 #include "vtkMPIController.h" 
   59 #include "libmesh/restore_warnings.h" 
   67 #define VTK_VERSION_LESS_THAN(major,minor,subminor)                     \ 
   68   ((LIBMESH_DETECTED_VTK_VERSION_MAJOR < (major) ||                     \ 
   69     (LIBMESH_DETECTED_VTK_VERSION_MAJOR == (major) && (LIBMESH_DETECTED_VTK_VERSION_MINOR < (minor) || \ 
   70                                                        (LIBMESH_DETECTED_VTK_VERSION_MINOR == (minor) && \ 
   71                                                         LIBMESH_DETECTED_VTK_VERSION_SUBMINOR < (subminor))))) ? 1 : 0) 
   73 #endif // LIBMESH_HAVE_VTK 
   84 #ifdef LIBMESH_HAVE_VTK
 
   95 #ifdef LIBMESH_HAVE_VTK
 
  106   std::vector<Number> soln;
 
  107   std::vector<std::string> names;
 
  115 #ifdef LIBMESH_HAVE_VTK 
  143 #if VTK_MAJOR_VERSION > 5 || (VTK_MAJOR_VERSION == 5 && VTK_MINOR_VERSION > 0) 
  167   typedef vtkSmartPointer<vtkXMLUnstructuredGridReader> MyReader;
 
  168   MyReader reader = MyReader::New();
 
  171   reader->SetFileName(
name.c_str());
 
  186   const unsigned int vtk_num_points = static_cast<unsigned int>(
_vtk_grid->GetNumberOfPoints());
 
  189   for (
unsigned int i=0; i<vtk_num_points; ++i)
 
  194       _vtk_grid->GetPoint(static_cast<vtkIdType>(i), pnt);
 
  195       Point xyz(pnt[0], pnt[1], pnt[2]);
 
  200   const unsigned int vtk_num_cells = static_cast<unsigned int>(
_vtk_grid->GetNumberOfCells());
 
  202   vtkSmartPointer<vtkGenericCell> cell = vtkSmartPointer<vtkGenericCell>::New();
 
  203   for (
unsigned int i=0; i<vtk_num_cells; ++i)
 
  214           mesh.
node_ptr(cast_int<dof_id_type>(cell->GetPointId(j)));
 
  217       std::vector<dof_id_type> conn;
 
  222       for (
unsigned int j=0,
 
  223            n_conn = cast_int<unsigned int>(conn.size());
 
  235   for (
unsigned char i=0; i!=4; ++i)
 
  241     libmesh_error_msg(
"Cannot open dimension "  \
 
  243                       << 
" mesh file when configured without "  \
 
  246 #endif // LIBMESH_DIM < 3 
  252                               const std::vector<Number> & soln,
 
  253                               const std::vector<std::string> & names)
 
  258   if (fname.substr(fname.rfind(
"."), fname.size()) != 
".pvtu")
 
  259     libmesh_do_once(
libMesh::err << 
"The .pvtu extension should be used when writing VTK files in libMesh.");
 
  265   if (!names.empty() && soln.empty())
 
  266     libmesh_error_msg(
"Empty soln vector in VTKIO::write_nodal_data().");
 
  272   _vtk_grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
 
  273   vtkSmartPointer<vtkXMLPUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLPUnstructuredGridWriter>::New();
 
  274 #ifdef LIBMESH_HAVE_MPI 
  276   vtkSmartPointer<vtkMPICommunicator> vtk_comm = vtkSmartPointer<vtkMPICommunicator>::New();
 
  277   MPI_Comm mpi_comm = 
mesh.
comm().get();
 
  278   vtkMPICommunicatorOpaqueComm vtk_opaque_comm(&mpi_comm);
 
  279   vtk_comm->InitializeExternal(&vtk_opaque_comm);
 
  281   vtkSmartPointer<vtkMPIController> vtk_mpi_ctrl = vtkSmartPointer<vtkMPIController>::New();
 
  282   vtk_mpi_ctrl->SetCommunicator(vtk_comm);
 
  284   writer->SetController(vtk_mpi_ctrl);
 
  295   if (names.size() > 0)
 
  297       std::size_t num_vars = names.size();
 
  298       std::vector<Number> local_values;
 
  300 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 
  301       std::vector<Real> local_real_values;
 
  304       for (std::size_t variable=0; variable<num_vars; ++variable)
 
  308 #ifdef LIBMESH_USE_COMPLEX_NUMBERS 
  310           local_real_values.resize(local_values.size());
 
  311           std::transform(local_values.begin(), local_values.end(),
 
  312                          local_real_values.begin(),
 
  313                          [](
Number x) { 
return x.real(); });
 
  317           local_real_values.resize(local_values.size());
 
  318           std::transform(local_values.begin(), local_values.end(),
 
  319                          local_real_values.begin(),
 
  320                          [](
Number x) { 
return x.imag(); });
 
  338   writer->SetGhostLevel(1);
 
  343 #if VTK_VERSION_LESS_THAN(6,0,0) 
  349   writer->SetFileName(fname.c_str());
 
  350   writer->SetDataModeToAscii();
 
  355 #if !VTK_VERSION_LESS_THAN(5,6,0) 
  356       writer->SetCompressorTypeToZLib();
 
  358       libmesh_do_once(
libMesh::err << 
"Compression not implemented with old VTK libs!" << std::endl;);
 
  387   vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
 
  388   vtkSmartPointer<vtkDoubleArray> pcoords = vtkSmartPointer<vtkDoubleArray>::New();
 
  390   pcoords->SetNumberOfComponents(LIBMESH_DIM);
 
  394   unsigned int local_node_counter = 0;
 
  398       const Node & node = *node_ptr;
 
  400       double pnt[3] = {0, 0, 0};
 
  401       for (
unsigned int i=0; i<LIBMESH_DIM; ++i)
 
  408 #if VTK_VERSION_LESS_THAN(7,1,0) 
  409       pcoords->InsertNextTupleValue(pnt);
 
  411       pcoords->InsertNextTuple(pnt);
 
  413       ++local_node_counter;
 
  417   points->SetData(pcoords);
 
  429   vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
 
  430   vtkSmartPointer<vtkIdList> pts = vtkSmartPointer<vtkIdList>::New();
 
  434   vtkSmartPointer<vtkIntArray> elem_id = vtkSmartPointer<vtkIntArray>::New();
 
  435   elem_id->SetName(
"libmesh_elem_id");
 
  436   elem_id->SetNumberOfComponents(1);
 
  438   vtkSmartPointer<vtkIntArray> subdomain_id = vtkSmartPointer<vtkIntArray>::New();
 
  439   subdomain_id->SetName(
"subdomain_id");
 
  440   subdomain_id->SetNumberOfComponents(1);
 
  442   vtkSmartPointer<vtkIntArray> elem_proc_id = vtkSmartPointer<vtkIntArray>::New();
 
  443   elem_proc_id->SetName(
"processor_id");
 
  444   elem_proc_id->SetNumberOfComponents(1);
 
  446   unsigned active_element_counter = 0;
 
  449       pts->SetNumberOfIds(elem->n_nodes());
 
  452       std::vector<dof_id_type> conn;
 
  453       elem->connectivity(0, 
VTK, conn);
 
  455       for (
unsigned int i=0,
 
  456            n_conn = cast_int<unsigned int>(conn.size());
 
  469               double pt[3] = {0., 0., 0.};
 
  470               for (
unsigned int d=0; d<LIBMESH_DIM; ++d)
 
  474               vtkIdType local = 
_vtk_grid->GetPoints()->InsertNextPoint(pt);
 
  478                 cast_int<dof_id_type>(local);
 
  486       vtkIdType vtkcellid = cells->InsertNextCell(pts);
 
  489       elem_id->InsertTuple1(vtkcellid, elem->id());
 
  490       subdomain_id->InsertTuple1(vtkcellid, elem->subdomain_id());
 
  491       elem_proc_id->InsertTuple1(vtkcellid, elem->processor_id());
 
  492       ++active_element_counter;
 
  495   _vtk_grid->SetCells(types.data(), cells);
 
  496   _vtk_grid->GetCellData()->AddArray(elem_id);
 
  497   _vtk_grid->GetCellData()->AddArray(subdomain_id);
 
  498   _vtk_grid->GetCellData()->AddArray(elem_proc_id);
 
  502                                const std::vector<Real> & local_values)
 
  504   vtkSmartPointer<vtkDoubleArray> 
data = vtkSmartPointer<vtkDoubleArray>::New();
 
  514     data->SetValue(i, local_values[i]);
 
  521                                   std::size_t variable,
 
  522                                   const std::vector<Number> & soln,
 
  523                                   const std::vector<std::string> & names)
 
  526   std::size_t num_vars = names.size();
 
  529   local_values.clear();
 
  536       std::map<dof_id_type, dof_id_type>::iterator local_node_it = 
_local_node_map.find(k);
 
  540       local_values[local_node_it->second] = soln[k*num_vars + variable];
 
  604 #else // !LIBMESH_HAVE_VTK 
  608   libmesh_error_msg(
"Cannot read VTK file: " << 
name \
 
  609                     << 
"\nYou must have VTK installed and correctly configured to read VTK meshes.");
 
  615                               const std::vector<Number> &,
 
  616                               const std::vector<std::string> &)
 
  618   libmesh_error_msg(
"Cannot write VTK file: " << fname                  \
 
  619                     << 
"\nYou must have VTK installed and correctly configured to read VTK meshes.");
 
  623 #endif // LIBMESH_HAVE_VTK