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