36 #include <boost/scoped_array.hpp> 37 #include "VtkMeshWriter.hpp" 38 #include "DistributedTetrahedralMesh.hpp" 39 #include "MixedDimensionMesh.hpp" 40 #include "NodesOnlyMesh.hpp" 43 #include "vtkQuadraticTetra.h" 44 #include "vtkQuadraticTriangle.h" 50 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
52 const std::string& rBaseName,
53 const bool& rCleanDirectory)
55 mWriteParallelFiles(false)
63 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
69 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
73 vtkPoints* p_pts = vtkPoints::New(VTK_DOUBLE);
74 p_pts->GetData()->SetName(
"Vertex positions");
75 for (
unsigned item_num=0; item_num<this->
GetNumNodes(); item_num++)
77 std::vector<double> current_item = this->
GetNextNode();
79 for (
unsigned dim=SPACE_DIM; dim<3; dim++)
81 current_item.push_back(0.0);
83 assert(current_item.size() == 3);
84 p_pts->InsertPoint(item_num, current_item[0], current_item[1], current_item[2]);
90 for (
unsigned item_num=0; item_num<this->
GetNumElements(); item_num++)
94 assert((current_element.size() == ELEMENT_DIM + 1) || (current_element.size() == (ELEMENT_DIM+1)*(ELEMENT_DIM+2)/2));
96 vtkCell* p_cell=
nullptr;
97 if (ELEMENT_DIM == 3 && current_element.size() == 4)
99 p_cell = vtkTetra::New();
101 else if (ELEMENT_DIM == 3 && current_element.size() == 10)
103 p_cell = vtkQuadraticTetra::New();
105 else if (ELEMENT_DIM == 2 && current_element.size() == 3)
107 p_cell = vtkTriangle::New();
109 else if (ELEMENT_DIM == 2 && current_element.size() == 6)
111 p_cell = vtkQuadraticTriangle::New();
113 else if (ELEMENT_DIM == 1)
115 p_cell = vtkLine::New();
119 vtkIdList* p_cell_id_list = p_cell->GetPointIds();
120 for (
unsigned j = 0; j < current_element.size(); ++j)
122 p_cell_id_list->SetId(j, current_element[j]);
126 if (SPACE_DIM == 2 && current_element.size() == 6)
128 p_cell_id_list->SetId(3, current_element[5]);
129 p_cell_id_list->SetId(4, current_element[3]);
130 p_cell_id_list->SetId(5, current_element[4]);
155 std::vector<unsigned> current_element = cable_element_data.
NodeIndices;
157 assert(current_element.size() == 2);
158 vtkCell* p_cell=vtkLine::New();
159 vtkIdList* p_cell_id_list = p_cell->GetPointIds();
160 for (
unsigned j = 0; j < 2; ++j)
162 p_cell_id_list->SetId(j, current_element[j]);
172 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
179 *p_vtu_file <<
"\n" << comment <<
"\n";
183 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
190 vtkXMLUnstructuredGridWriter* p_writer = vtkXMLUnstructuredGridWriter::New();
191 #if VTK_MAJOR_VERSION >= 6 197 p_writer->SetFileName(vtk_file_name.c_str());
206 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
209 vtkDoubleArray* p_scalars = vtkDoubleArray::New();
210 p_scalars->SetName(dataName.c_str());
211 for (
unsigned i=0; i<dataPayload.size(); i++)
213 p_scalars->InsertNextValue(dataPayload[i]);
217 p_cell_data->AddArray(p_scalars);
221 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
225 for (
unsigned i = 0; i < num_cell_arrays; i++)
233 assert((
unsigned)array->GetNumberOfTuples() == this->
mpDistributedMesh->GetNumLocalElements());
234 num_cable_pads = this->
mpMixedMesh->GetNumLocalCableElements();
238 assert((
unsigned)array->GetNumberOfTuples() == this->
GetNumElements());
242 assert(array->GetNumberOfComponents() <= 3);
243 double null_data[3] = {0.0, 0.0, 0.0};
246 for (
unsigned new_index = 0; new_index < num_cable_pads; new_index++)
248 array->InsertNextTuple(null_data);
254 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
257 vtkDoubleArray* p_vectors = vtkDoubleArray::New();
258 p_vectors->SetName(dataName.c_str());
259 p_vectors->SetNumberOfComponents(3);
260 for (
unsigned i=0; i<dataPayload.size(); i++)
262 for (
unsigned j=0; j<SPACE_DIM; j++)
264 p_vectors->InsertNextValue(dataPayload[i][j]);
267 for (
unsigned j=SPACE_DIM; j<3; j++)
269 p_vectors->InsertNextValue(0.0);
274 p_cell_data->AddArray(p_vectors);
278 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
281 assert(SPACE_DIM != 1);
283 vtkDoubleArray* p_vectors = vtkDoubleArray::New();
284 p_vectors->SetName(dataName.c_str());
285 p_vectors->SetNumberOfComponents(SPACE_DIM*SPACE_DIM);
286 for (
unsigned i=0; i<dataPayload.size(); i++)
290 p_vectors->InsertNextValue(dataPayload[i](0));
291 p_vectors->InsertNextValue(dataPayload[i](1));
292 p_vectors->InsertNextValue(dataPayload[i](1));
293 p_vectors->InsertNextValue(dataPayload[i](2));
295 else if (SPACE_DIM == 3)
297 p_vectors->InsertNextValue(dataPayload[i](0));
298 p_vectors->InsertNextValue(dataPayload[i](1));
299 p_vectors->InsertNextValue(dataPayload[i](2));
300 p_vectors->InsertNextValue(dataPayload[i](1));
301 p_vectors->InsertNextValue(dataPayload[i](3));
302 p_vectors->InsertNextValue(dataPayload[i](4));
303 p_vectors->InsertNextValue(dataPayload[i](2));
304 p_vectors->InsertNextValue(dataPayload[i](4));
305 p_vectors->InsertNextValue(dataPayload[i](5));
310 p_cell_data->AddArray(p_vectors);
314 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
317 assert(SPACE_DIM != 1);
319 vtkDoubleArray* p_vectors = vtkDoubleArray::New();
320 p_vectors->SetName(dataName.c_str());
321 p_vectors->SetNumberOfComponents(SPACE_DIM*SPACE_DIM);
322 for (
unsigned i=0; i<dataPayload.size(); i++)
326 p_vectors->InsertNextValue(dataPayload[i](0,0));
327 p_vectors->InsertNextValue(dataPayload[i](0,1));
328 p_vectors->InsertNextValue(dataPayload[i](1,0));
329 p_vectors->InsertNextValue(dataPayload[i](1,1));
331 else if (SPACE_DIM == 3)
333 p_vectors->InsertNextValue(dataPayload[i](0,0));
334 p_vectors->InsertNextValue(dataPayload[i](0,1));
335 p_vectors->InsertNextValue(dataPayload[i](0,2));
336 p_vectors->InsertNextValue(dataPayload[i](1,0));
337 p_vectors->InsertNextValue(dataPayload[i](1,1));
338 p_vectors->InsertNextValue(dataPayload[i](1,2));
339 p_vectors->InsertNextValue(dataPayload[i](2,0));
340 p_vectors->InsertNextValue(dataPayload[i](2,1));
341 p_vectors->InsertNextValue(dataPayload[i](2,2));
346 p_cell_data->AddArray(p_vectors);
351 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
354 vtkDoubleArray* p_scalars = vtkDoubleArray::New();
355 p_scalars->SetName(dataName.c_str());
377 boost::scoped_array<double> send_data(
new double[number_of_nodes_to_send]);
378 boost::scoped_array<double> receive_data(
new double[number_of_nodes_to_receive]);
380 for (
unsigned node = 0; node < number_of_nodes_to_send; node++)
383 unsigned local_node_index = global_node_index
385 send_data[node] = dataPayload[local_node_index];
391 ret = MPI_Sendrecv(send_data.get(), number_of_nodes_to_send,
394 receive_data.get(), number_of_nodes_to_receive,
397 PETSC_COMM_WORLD, &status);
399 assert ( ret == MPI_SUCCESS );
403 for (
unsigned node = 0; node < number_of_nodes_to_receive; node++ )
408 dataPayload[halo_index] = receive_data[node];
414 for (
unsigned i=0; i<dataPayload.size(); i++)
416 p_scalars->InsertNextValue(dataPayload[i]);
420 p_point_data->AddArray(p_scalars);
425 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
428 vtkDoubleArray* p_vectors = vtkDoubleArray::New();
429 p_vectors->SetName(dataName.c_str());
450 boost::scoped_array<double> send_data(
new double[number_of_nodes_to_send * SPACE_DIM]);
451 boost::scoped_array<double> receive_data(
new double[number_of_nodes_to_receive * SPACE_DIM]);
453 for (
unsigned node = 0; node < number_of_nodes_to_send; node++)
456 unsigned local_node_index = global_node_index
458 for (
unsigned j=0; j<SPACE_DIM; j++)
460 send_data[ node*SPACE_DIM + j ] = dataPayload[local_node_index][j];
466 ret = MPI_Sendrecv(send_data.get(), number_of_nodes_to_send * SPACE_DIM,
469 receive_data.get(), number_of_nodes_to_receive * SPACE_DIM,
472 PETSC_COMM_WORLD, &status);
474 assert ( ret == MPI_SUCCESS );
477 for (
unsigned node = 0; node < number_of_nodes_to_receive; node++ )
482 for (
unsigned j=0; j<SPACE_DIM; j++)
484 dataPayload[halo_index][j] = receive_data[ node*SPACE_DIM + j ];
490 p_vectors->SetNumberOfComponents(3);
491 for (
unsigned i=0; i<dataPayload.size(); i++)
493 for (
unsigned j=0; j<SPACE_DIM; j++)
495 p_vectors->InsertNextValue(dataPayload[i][j]);
498 for (
unsigned j=SPACE_DIM; j<3; j++)
500 p_vectors->InsertNextValue(0.0);
505 p_point_data->AddArray(p_vectors);
509 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
512 assert(SPACE_DIM != 1);
514 vtkDoubleArray* p_vectors = vtkDoubleArray::New();
515 p_vectors->SetName(dataName.c_str());
516 p_vectors->SetNumberOfComponents(SPACE_DIM*SPACE_DIM);
517 for (
unsigned i=0; i<dataPayload.size(); i++)
521 p_vectors->InsertNextValue(dataPayload[i](0,0));
522 p_vectors->InsertNextValue(dataPayload[i](0,1));
523 p_vectors->InsertNextValue(dataPayload[i](1,0));
524 p_vectors->InsertNextValue(dataPayload[i](1,1));
526 else if (SPACE_DIM == 3)
528 p_vectors->InsertNextValue(dataPayload[i](0,0));
529 p_vectors->InsertNextValue(dataPayload[i](0,1));
530 p_vectors->InsertNextValue(dataPayload[i](0,2));
531 p_vectors->InsertNextValue(dataPayload[i](1,0));
532 p_vectors->InsertNextValue(dataPayload[i](1,1));
533 p_vectors->InsertNextValue(dataPayload[i](1,2));
534 p_vectors->InsertNextValue(dataPayload[i](2,0));
535 p_vectors->InsertNextValue(dataPayload[i](2,1));
536 p_vectors->InsertNextValue(dataPayload[i](2,2));
541 p_point_data->AddArray(p_vectors);
545 template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
554 EXCEPTION(
"Cannot write parallel files using a sequential mesh");
595 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
598 bool keepOriginalElementIndexing)
611 vtkPoints* p_pts = vtkPoints::New(VTK_DOUBLE);
612 p_pts->GetData()->SetName(
"Vertex positions");
619 c_vector<double, SPACE_DIM> current_item = node_iter->rGetLocation();
622 p_pts->InsertNextPoint(current_item[0], current_item[1], current_item[2]);
624 else if (SPACE_DIM == 2)
626 p_pts->InsertNextPoint(current_item[0], current_item[1], 0.0);
630 p_pts->InsertNextPoint(current_item[0], 0.0, 0.0);
641 c_vector<double, SPACE_DIM> current_item = (*halo_iter)->rGetLocation();
644 p_pts->InsertNextPoint(current_item[0], current_item[1], current_item[2]);
646 else if (SPACE_DIM == 2)
648 p_pts->InsertNextPoint(current_item[0], current_item[1], 0.0);
652 p_pts->InsertNextPoint(current_item[0], 0.0, 0.0);
665 vtkCell* p_cell=
nullptr;
667 if (ELEMENT_DIM == 3)
669 p_cell = vtkTetra::New();
671 else if (ELEMENT_DIM == 2)
673 p_cell = vtkTriangle::New();
677 p_cell = vtkLine::New();
679 vtkIdList* p_cell_id_list = p_cell->GetPointIds();
680 for (
unsigned j = 0; j < ELEMENT_DIM+1; ++j)
682 unsigned global_node_index = elem_iter->GetNodeGlobalIndex(j);
689 if (this->mpMixedMesh )
695 elem_iter != this->mpMixedMesh->GetCableElementIteratorEnd();
698 radii.push_back((*elem_iter)->GetAttribute());
699 vtkCell* p_cell=vtkLine::New();
700 vtkIdList* p_cell_id_list = p_cell->GetPointIds();
701 for (
unsigned j = 0; j < 2; ++j)
703 unsigned global_node_index = (*elem_iter)->GetNodeGlobalIndex(j);
717 vtkXMLPUnstructuredGridWriter* p_writer = vtkXMLPUnstructuredGridWriter::New();
719 p_writer->SetDataModeToBinary();
727 #if VTK_MAJOR_VERSION >= 6 733 p_writer->SetFileName(pvtk_file_name.c_str());
740 std::stringstream filepath;
ElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
ElementData GetNextCableElement()
unsigned GetNumCableElements()
ElementIterator GetElementIteratorEnd()
ElementData GetNextBoundaryElement()
#define EXCEPTION(message)
vtkUnstructuredGrid * mpVtkUnstructedMesh
std::vector< Node< SPACE_DIM > * >::const_iterator HaloNodeIterator
void SetParallelFiles(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
void AddCellData(std::string name, std::vector< double > data)
void AddProvenance(std::string fileName)
NodeIterator GetNodeIteratorEnd()
virtual unsigned GetNumNodes()
OutputFileHandler * mpOutputFileHandler
std::string GetOutputDirectoryFullPath() const
std::vector< unsigned > NodeIndices
void WriteFilesUsingMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool keepOriginalElementIndexing=true)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
std::vector< double > GetNextNode()
DistributedTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * mpDistributedMesh
unsigned GetNumLocalElements() const
void AddTensorCellData(std::string name, std::vector< c_vector< double, SPACE_DIM *(SPACE_DIM+1)/2 > > data)
ElementData GetNextElement()
void AddTensorPointData(std::string name, std::vector< c_matrix< double, SPACE_DIM, SPACE_DIM > > data)
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
std::vector< std::vector< unsigned > > mNodesToReceivePerProcess
MixedDimensionMesh< ELEMENT_DIM, SPACE_DIM > * mpMixedMesh
NodesOnlyMesh< SPACE_DIM > * mpNodesOnlyMesh
unsigned GetNumElements()
std::vector< std::vector< unsigned > > mNodesToSendPerProcess
static std::string GetProvenanceString()
virtual void WriteFilesUsingMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool keepOriginalElementIndexing=true)
std::map< unsigned, unsigned > mGlobalToNodeIndexMap
VtkMeshWriter(const std::string &rDirectory, const std::string &rBaseName, const bool &rCleanDirectory=true)
void AddPointData(std::string name, std::vector< double > data)
unsigned GetNumBoundaryFaces()
std::vector< Element< 1, SPACE_DIM > * >::const_iterator CableElementIterator