void TestMeshWriterWithDeletedNode() throw (Exception) { // Create mesh VertexMeshReader<2,2> mesh_reader("mesh/test/data/TestVertexMesh/honeycomb_vertex_mesh_3_by_3"); MutableVertexMesh<2,2> mesh; mesh.ConstructFromMeshReader(mesh_reader); TS_ASSERT_EQUALS(mesh.GetNumNodes(), 30u); TS_ASSERT_EQUALS(mesh.GetNumElements(), 9u); /* * Delete element 0. This element contains 3 nodes that are * not contained in any other element and so will be marked * as deleted. */ mesh.DeleteElementPriorToReMesh(0); // Write mesh to file VertexMeshWriter<2,2> mesh_writer("TestMeshWriterWithDeletedNode", "vertex_mesh"); TS_ASSERT_THROWS_NOTHING(mesh_writer.WriteFilesUsingMesh(mesh)); // Read mesh back in from file std::string output_dir = mesh_writer.GetOutputDirectory(); VertexMeshReader<2,2> mesh_reader2(output_dir + "vertex_mesh"); // We should have one less element and three less nodes TS_ASSERT_EQUALS(mesh_reader2.GetNumNodes(), 27u); TS_ASSERT_EQUALS(mesh_reader2.GetNumElements(), 8u); }
void AbstractContinuumMechanicsSolver<DIM>::CreateVtkOutput(std::string spatialSolutionName) { if (this->mOutputDirectory=="") { EXCEPTION("No output directory was given so no output was written, cannot convert to VTK format"); } #ifdef CHASTE_VTK VtkMeshWriter<DIM, DIM> mesh_writer(this->mOutputDirectory + "/vtk", "solution", true); mesh_writer.AddPointData(spatialSolutionName, this->rGetSpatialSolution()); if (mCompressibilityType==INCOMPRESSIBLE) { mesh_writer.AddPointData("Pressure", rGetPressures()); } //Output the element attribute as cell data. std::vector<double> element_attribute; for(typename QuadraticMesh<DIM>::ElementIterator iter = this->mrQuadMesh.GetElementIteratorBegin(); iter != this->mrQuadMesh.GetElementIteratorEnd(); ++iter) { element_attribute.push_back(iter->GetAttribute()); } mesh_writer.AddCellData("Attribute", element_attribute); mesh_writer.WriteFilesUsingMesh(this->mrQuadMesh); #endif }
void TestReadingAndWritingElementAttributes() throw(Exception) { // Read in a mesh with element attributes VertexMeshReader<2,2> mesh_reader("mesh/test/data/TestVertexMeshReader2d/vertex_mesh_with_element_attributes"); TS_ASSERT_EQUALS(mesh_reader.GetNumElements(), 2u); TS_ASSERT_EQUALS(mesh_reader.GetNumElementAttributes(), 1u); // Construct the mesh VertexMesh<2,2> mesh; mesh.ConstructFromMeshReader(mesh_reader); TS_ASSERT_EQUALS(mesh.GetElement(0)->GetUnsignedAttribute(), 97u); TS_ASSERT_EQUALS(mesh.GetElement(1)->GetUnsignedAttribute(), 152u); // Write the mesh to file // Nested scope so the reader is destroyed before we try writing to the folder again { VertexMeshWriter<2,2> mesh_writer("TestReadingAndWritingElementAttributes", "vertex_mesh_with_element_attributes"); mesh_writer.WriteFilesUsingMesh(mesh); // Now read in the mesh that was written OutputFileHandler handler("TestReadingAndWritingElementAttributes", false); VertexMeshReader<2,2> mesh_reader2(handler.GetOutputDirectoryFullPath() + "vertex_mesh_with_element_attributes"); TS_ASSERT_EQUALS(mesh_reader2.GetNumElements(), 2u); TS_ASSERT_EQUALS(mesh_reader2.GetNumElementAttributes(), 1u); // Construct the mesh again VertexMesh<2,2> mesh2; mesh2.ConstructFromMeshReader(mesh_reader); TS_ASSERT_EQUALS(mesh2.GetElement(0)->GetUnsignedAttribute(), 97u); TS_ASSERT_EQUALS(mesh2.GetElement(1)->GetUnsignedAttribute(), 152u); } // For coverage, repeat this test for a vertex mesh whose elements have faces VertexMeshReader<3,3> mesh_reader3d("mesh/test/data/TestVertexMeshWriter/vertex_mesh_3d_with_faces_and_attributes"); TS_ASSERT_EQUALS(mesh_reader3d.GetNumElements(), 1u); TS_ASSERT_EQUALS(mesh_reader3d.GetNumElementAttributes(), 1u); // Construct the mesh VertexMesh<3,3> mesh3d; mesh3d.ConstructFromMeshReader(mesh_reader3d); TS_ASSERT_EQUALS(mesh3d.GetElement(0)->GetUnsignedAttribute(), 49u); // Write the mesh to file VertexMeshWriter<3,3> mesh_writer3d("TestReadingAndWritingElementAttributes", "vertex_mesh_3d_with_faces_and_attributes"); mesh_writer3d.WriteFilesUsingMesh(mesh3d); // Now read in the mesh that was written OutputFileHandler handler3d("TestReadingAndWritingElementAttributes", false); VertexMeshReader<3,3> mesh_reader3d2(handler3d.GetOutputDirectoryFullPath() + "vertex_mesh_3d_with_faces_and_attributes"); TS_ASSERT_EQUALS(mesh_reader3d2.GetNumElements(), 1u); TS_ASSERT_EQUALS(mesh_reader3d2.GetNumElementAttributes(), 1u); // Construct the mesh again VertexMesh<3,3> mesh3d2; mesh3d2.ConstructFromMeshReader(mesh_reader3d2); TS_ASSERT_EQUALS(mesh3d2.GetElement(0)->GetUnsignedAttribute(), 49u); }
void RunTest(unsigned numStepsInEachDimension) { MeshEventHandler::Reset(); unsigned nodes = SmallPow(numStepsInEachDimension+1, 3); if (PetscTools::AmMaster()) { std::cout<<"Number steps per dimension = " << std::setw(12) << numStepsInEachDimension<<std::endl; std::cout<<"Number nodes = " << std::setw(12) << nodes<<std::endl; } std::string file_name = "cuboid"; std::stringstream directory_stream; directory_stream << "TestMeshWritersWeekly/steps_" << std::setw(12) << std::setfill('0')<< numStepsInEachDimension; std::string directory_name = directory_stream.str(); DistributedTetrahedralMesh<3,3> cuboid_mesh; cuboid_mesh.ConstructCuboid(numStepsInEachDimension, numStepsInEachDimension, numStepsInEachDimension); TS_ASSERT_EQUALS(cuboid_mesh.GetNumNodes(), nodes); MeshEventHandler::BeginEvent(MeshEventHandler::TRIANGLES); { TrianglesMeshWriter<3,3> mesh_writer(directory_name, file_name, false); mesh_writer.WriteFilesUsingMesh(cuboid_mesh); } MeshEventHandler::EndEvent(MeshEventHandler::TRIANGLES); MeshEventHandler::BeginEvent(MeshEventHandler::BINTRI); { TrianglesMeshWriter<3,3> bin_mesh_writer(directory_name, file_name+"_bin", false); bin_mesh_writer.SetWriteFilesAsBinary(); bin_mesh_writer.WriteFilesUsingMesh(cuboid_mesh); } MeshEventHandler::EndEvent(MeshEventHandler::BINTRI); #ifdef CHASTE_VTK MeshEventHandler::BeginEvent(MeshEventHandler::VTK); { VtkMeshWriter<3,3> vtk_writer(directory_name, file_name, false); vtk_writer.WriteFilesUsingMesh(cuboid_mesh); } MeshEventHandler::EndEvent(MeshEventHandler::VTK); MeshEventHandler::BeginEvent(MeshEventHandler::PVTK); { VtkMeshWriter<3,3> parallel_vtk_writer(directory_name, file_name+"par",false); parallel_vtk_writer.SetParallelFiles(cuboid_mesh); std::vector<double> dummy_data(cuboid_mesh.GetNumLocalNodes(), PetscTools::GetMyRank()); parallel_vtk_writer.AddPointData("Process", dummy_data); parallel_vtk_writer.WriteFilesUsingMesh(cuboid_mesh); } MeshEventHandler::EndEvent(MeshEventHandler::PVTK); #endif //CHASTE_VTK MeshEventHandler::Headings(); MeshEventHandler::Report(); }
void CellBasedPdeHandler<DIM>::OpenResultsFiles(std::string outputDirectory) { // If appropriate, make a coarse mesh which exactly overlays the lattice sites of a PottsMesh (used for all OnLattice simulations) if ((dynamic_cast<MultipleCaBasedCellPopulation<DIM>*>(mpCellPopulation) != NULL) && mpCoarsePdeMesh==NULL) { assert(DIM ==2); ChasteCuboid<DIM> cuboid = mpCellPopulation->rGetMesh().CalculateBoundingBox(); // Currently only works with square meshes assert(cuboid.GetWidth(0) == cuboid.GetWidth(1)); UseCoarsePdeMesh(1, cuboid, false); } // If using a NodeBasedCellPopulation a VertexBasedCellPopulation, a MultipleCABasedCellPopulation or a PottsBasedCellPopulation, mpCoarsePdeMesh must be set up if (PdeSolveNeedsCoarseMesh() && mpCoarsePdeMesh==NULL) { EXCEPTION("Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh()."); } if (mpCoarsePdeMesh != NULL) { InitialiseCellPdeElementMap(); // Write mesh to file TrianglesMeshWriter<DIM,DIM> mesh_writer(outputDirectory+"/coarse_mesh_output", "coarse_mesh",false); mesh_writer.WriteFilesUsingMesh(*mpCoarsePdeMesh); } if (PetscTools::AmMaster()) { OutputFileHandler output_file_handler(outputDirectory+"/", false); if (mpCoarsePdeMesh != NULL) { mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizcoarsepdesolution"); } else { mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution"); } if (mWriteAverageRadialPdeSolution) { mpAverageRadialPdeSolutionResultsFile = output_file_handler.OpenOutputFile("radial_dist.dat"); } } mDirPath = outputDirectory; // caching the path to the output directory for VTK //double current_time = SimulationTime::Instance()->GetTime(); //WritePdeSolution(current_time); }
void TestWritingCableFilesUsingMeshReader() throw(Exception) { std::string mesh_base("mesh/test/data/mixed_dimension_meshes/2D_0_to_1mm_200_elements"); TrianglesMeshReader<2,2> reader(mesh_base); TrianglesMeshWriter<2,2> mesh_writer("TestMixedDimensionMesh", "CableMeshFromReader"); mesh_writer.WriteFilesUsingMeshReader(reader); PetscTools::Barrier("TestWritingCableFilesUsingMeshReader"); FileFinder generated("TestMixedDimensionMesh/CableMeshFromReader.cable",RelativeTo::ChasteTestOutput); FileFinder reference("mesh/test/data/mixed_dimension_meshes/2D_0_to_1mm_200_elements.cable", RelativeTo::ChasteSourceRoot); FileComparison comparer(generated,reference); TS_ASSERT(comparer.CompareFiles()); }
void TestWritingCableFiles() throw(Exception) { std::string mesh_base("mesh/test/data/mixed_dimension_meshes/2D_0_to_1mm_200_elements"); TrianglesMeshReader<2,2> reader(mesh_base); MixedDimensionMesh<2,2> mesh(DistributedTetrahedralMeshPartitionType::DUMB); mesh.ConstructFromMeshReader(reader); TrianglesMeshWriter<2,2> mesh_writer("TestMixedDimensionMesh", "CableMesh", true); mesh_writer.WriteFilesUsingMesh(mesh); FileFinder generated("TestMixedDimensionMesh/CableMesh.cable",RelativeTo::ChasteTestOutput); FileFinder reference("mesh/test/data/mixed_dimension_meshes/2D_0_to_1mm_200_elements.cable", RelativeTo::ChasteSourceRoot); FileComparison comparer(generated,reference); TS_ASSERT(comparer.CompareFiles()); }
/* * Failing test for ReMesh (see #1275) */ void noTestCylindricalReMeshFailingTest() throw (Exception) { // Load a problematic mesh TrianglesMeshReader<2,2> mesh_reader("cell_based/test/data/TestCylindricalMeshBug/mesh"); Cylindrical2dMesh mesh(20); mesh.ConstructFromMeshReader(mesh_reader); TS_ASSERT_DELTA(mesh.GetWidth(0), 20, 1e-3); TrianglesMeshWriter<2,2> mesh_writer("TestCylindricalMeshBug", "mesh", false); mesh_writer.WriteFilesUsingMesh(mesh); // Use showme to view this mesh NodeMap map(mesh.GetNumNodes()); mesh.ReMesh(map); }
void MeshBasedCellPopulationWithGhostNodes<DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK if (this->mpVoronoiTessellation != NULL) { unsigned num_timesteps = SimulationTime::Instance()->GetTimeStepsElapsed(); std::stringstream time; time << num_timesteps; // Create mesh writer for VTK output VertexMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results", false); // Iterate over any cell writers that are present unsigned num_vtk_cells = this->mpVoronoiTessellation->GetNumElements(); for (typename std::vector<boost::shared_ptr<AbstractCellWriter<DIM, DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_vtk_cells); // Loop over elements of mpVoronoiTessellation for (typename VertexMesh<DIM, DIM>::VertexElementIterator elem_iter = this->mpVoronoiTessellation->GetElementIteratorBegin(); elem_iter != this->mpVoronoiTessellation->GetElementIteratorEnd(); ++elem_iter) { // Get the indices of this element and the corresponding node in mrMesh unsigned elem_index = elem_iter->GetIndex(); unsigned node_index = this->mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index); // If this node corresponds to a ghost node, set any "cell" data to be -1.0 if (this->IsGhostNode(node_index)) { // Populate the vector of VTK cell data vtk_cell_data[elem_index] = -1.0; } else { // Get the cell corresponding to this node CellPtr p_cell = this->GetCellUsingLocationIndex(node_index); // Populate the vector of VTK cell data vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this); } } mesh_writer.AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // Next, record which nodes are ghost nodes // Note that the cell writer hierarchy can not be used to do this as ghost nodes don't have corresponding cells. std::vector<double> ghosts(num_vtk_cells); for (typename VertexMesh<DIM, DIM>::VertexElementIterator elem_iter = this->mpVoronoiTessellation->GetElementIteratorBegin(); elem_iter != this->mpVoronoiTessellation->GetElementIteratorEnd(); ++elem_iter) { unsigned elem_index = elem_iter->GetIndex(); unsigned node_index = this->mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index); ghosts[elem_index] = (double) (this->IsGhostNode(node_index)); } mesh_writer.AddCellData("Non-ghosts", ghosts); ///\todo #1975 - deal with possibility of information stored in CellData mesh_writer.WriteVtkUsingMesh(*(this->mpVoronoiTessellation), time.str()); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << ".vtu\"/>\n"; } #endif //CHASTE_VTK }
void TestGeneralConvolution3DWithHomogeneousUblas() { TrianglesMeshReader<3,3> mesh_reader("mesh/test/data/cube_136_elements"); TetrahedralMesh<3,3> mesh; mesh.ConstructFromMeshReader(mesh_reader); TS_ASSERT_DELTA(mesh.GetVolume(), 1.0, 1e-6); TS_ASSERT_DELTA(mesh.GetSurfaceArea(), 6.0, 1e-6); // Change coordinates c_matrix<double, 4, 4> x_rotation_matrix = identity_matrix<double>(4); c_matrix<double, 4, 4> y_rotation_matrix = identity_matrix<double>(4); c_matrix<double, 4, 4> z_rotation_matrix = identity_matrix<double>(4); c_matrix<double, 4, 4> translation_matrix = identity_matrix<double>(4); double theta = 0.7; double phi = 0.3; double psi = 1.4; x_rotation_matrix(1,1) = cos(theta); x_rotation_matrix(1,2) = sin(theta); x_rotation_matrix(2,1) = -sin(theta); x_rotation_matrix(2,2) = cos(theta); y_rotation_matrix(0,0) = cos(phi); y_rotation_matrix(0,2) = -sin(phi); y_rotation_matrix(2,0) = sin(phi); y_rotation_matrix(2,2) = cos(phi); z_rotation_matrix(0,0) = cos(psi); z_rotation_matrix(0,1) = sin(psi); z_rotation_matrix(1,0) = -sin(psi); z_rotation_matrix(1,1) = cos(psi); translation_matrix(0,3) = 2.3; translation_matrix(1,3) = 3.1; translation_matrix(2,3) = 1.7; /* Note: because we are using column-major vectors this tranformation: RotX(theta) . RotY(phi) . RotZ(psi) . Trans(...) is actually being applied right-to-left See test below. */ c_matrix<double, 4, 4> transformation_matrix = prod (x_rotation_matrix, y_rotation_matrix); transformation_matrix = prod (transformation_matrix, z_rotation_matrix); transformation_matrix = prod (transformation_matrix, translation_matrix); for (unsigned i=0; i<mesh.GetNumNodes(); i++) { Node<3>* p_node = mesh.GetNode(i); ChastePoint<3> point = p_node->GetPoint(); c_vector<double, 4> point_location; point_location[0] = point[0]; point_location[1] = point[1]; point_location[2] = point[2]; point_location[3] = 1.0; c_vector<double, 4> new_point_location = prod(transformation_matrix, point_location); TS_ASSERT_EQUALS(new_point_location[3], 1.0); point.SetCoordinate(0,new_point_location[0]); point.SetCoordinate(1,new_point_location[1]); point.SetCoordinate(2,new_point_location[2]); p_node->SetPoint(point); } mesh.RefreshMesh(); TS_ASSERT_DELTA(mesh.GetVolume(), 1.0, 1e-6); TS_ASSERT_DELTA(mesh.GetSurfaceArea(), 6.0, 1e-6); ChastePoint<3> corner_after = mesh.GetNode(6)->GetPoint(); TS_ASSERT_DELTA(corner_after[0], 3.59782, 5e-5); TS_ASSERT_DELTA(corner_after[1], 0.583418, 5e-5); TS_ASSERT_DELTA(corner_after[2], 4.65889, 5e-5); // Write to file TrianglesMeshWriter<3,3> mesh_writer("","TransformedMesh"); mesh_writer.WriteFilesUsingMesh(mesh); /* * Now try tetview /tmp/chaste/testoutput/TransformedMesh */ }
void NodeBasedCellPopulationWithParticles<DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK // Store the present time as a string std::stringstream time; time << SimulationTime::Instance()->GetTimeStepsElapsed(); // Make sure the nodes are ordered contiguously in memory NodeMap map(1 + this->mpNodesOnlyMesh->GetMaximumNodeIndex()); this->mpNodesOnlyMesh->ReMesh(map); // Store the number of cells for which to output data to VTK unsigned num_nodes = this->GetNumNodes(); std::vector<double> rank(num_nodes); std::vector<double> particles(num_nodes); unsigned num_cell_data_items = 0; std::vector<std::string> cell_data_names; // We assume that the first cell is representative of all cells if (num_nodes > 0) { num_cell_data_items = this->Begin()->GetCellData()->GetNumItems(); cell_data_names = this->Begin()->GetCellData()->GetKeys(); } std::vector<std::vector<double> > cell_data; for (unsigned var=0; var<num_cell_data_items; var++) { std::vector<double> cell_data_var(num_nodes); cell_data.push_back(cell_data_var); } // Create mesh writer for VTK output VtkMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results_"+time.str(), false); mesh_writer.SetParallelFiles(*(this->mpNodesOnlyMesh)); // Iterate over any cell writers that are present for (typename std::vector<boost::shared_ptr<AbstractCellWriter<DIM, DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_nodes); // Loop over nodes for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin(); node_iter != this->mrMesh.GetNodeIteratorEnd(); ++node_iter) { unsigned node_index = node_iter->GetIndex(); // If this node is a particle (not a cell), then we set the 'dummy' VTK cell data for this to be -2.0... if (this->IsParticle(node_index)) { vtk_cell_data[node_index] = -2.0; } else { // ...otherwise we populate the vector of VTK cell data as usual CellPtr p_cell = this->GetCellUsingLocationIndex(node_index); vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this); } } mesh_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // Loop over cells for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin(); cell_iter != this->End(); ++cell_iter) { // Get the node index corresponding to this cell unsigned global_index = this->GetLocationIndexUsingCell(*cell_iter); unsigned node_index = this->rGetMesh().SolveNodeMapping(global_index); for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]); } rank[node_index] = (PetscTools::GetMyRank()); } mesh_writer.AddPointData("Process rank", rank); // Loop over nodes for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin(); node_iter != this->mrMesh.GetNodeIteratorEnd(); ++node_iter) { unsigned node_index = node_iter->GetIndex(); particles[node_index] = (double) (this->IsParticle(node_index)); } mesh_writer.AddPointData("Non-particles", particles); if (num_cell_data_items > 0) { for (unsigned var=0; var<cell_data.size(); var++) { mesh_writer.AddPointData(cell_data_names[var], cell_data[var]); } } mesh_writer.WriteFilesUsingMesh(*(this->mpNodesOnlyMesh)); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed(); *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed(); EXCEPT_IF_NOT(PetscTools::IsSequential()); { *(this->mpVtkMetaFile) << ".vtu\"/>\n"; } /* { // Parallel vtu files .vtu -> .pvtu *(this->mpVtkMetaFile) << ".pvtu\"/>\n"; }*/ #endif //CHASTE_VTK }
void MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK // Store the present time as a string unsigned num_timesteps = SimulationTime::Instance()->GetTimeStepsElapsed(); std::stringstream time; time << num_timesteps; // Store the number of cells for which to output data to VTK unsigned num_cells_from_mesh = GetNumNodes(); if (!mWriteVtkAsPoints && (mpVoronoiTessellation != NULL)) { num_cells_from_mesh = mpVoronoiTessellation->GetNumElements(); } // When outputting any CellData, we assume that the first cell is representative of all cells unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems(); std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys(); std::vector<std::vector<double> > cell_data; for (unsigned var=0; var<num_cell_data_items; var++) { std::vector<double> cell_data_var(num_cells_from_mesh); cell_data.push_back(cell_data_var); } if (mOutputMeshInVtk) { // Create mesh writer for VTK output VtkMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(rDirectory, "mesh_"+time.str(), false); mesh_writer.WriteFilesUsingMesh(rGetMesh()); } if (mWriteVtkAsPoints) { // Create mesh writer for VTK output VtkMeshWriter<SPACE_DIM, SPACE_DIM> cells_writer(rDirectory, "results_"+time.str(), false); // Iterate over any cell writers that are present unsigned num_cells = this->GetNumAllCells(); for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_cells); // Loop over cells for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = this->Begin(); cell_iter != this->End(); ++cell_iter) { // Get the node index corresponding to this cell unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter); // Populate the vector of VTK cell data vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(*cell_iter, this); } cells_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // Loop over cells for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = this->Begin(); cell_iter != this->End(); ++cell_iter) { // Get the node index corresponding to this cell unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter); for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]); } } for (unsigned var=0; var<num_cell_data_items; var++) { cells_writer.AddPointData(cell_data_names[var], cell_data[var]); } // Make a copy of the nodes in a disposable mesh for writing { std::vector<Node<SPACE_DIM>* > nodes; for (unsigned index=0; index<this->mrMesh.GetNumNodes(); index++) { Node<SPACE_DIM>* p_node = this->mrMesh.GetNode(index); nodes.push_back(p_node); } NodesOnlyMesh<SPACE_DIM> mesh; mesh.ConstructNodesWithoutMesh(nodes, 1.5); // Arbitrary cut off as connectivity not used. cells_writer.WriteFilesUsingMesh(mesh); } *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << ".vtu\"/>\n"; } else if (mpVoronoiTessellation != NULL) { // Create mesh writer for VTK output VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(rDirectory, "results", false); std::vector<double> cell_volumes(num_cells_from_mesh); // Iterate over any cell writers that are present unsigned num_cells = this->GetNumAllCells(); for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_cells); // Loop over elements of mpVoronoiTessellation for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin(); elem_iter != mpVoronoiTessellation->GetElementIteratorEnd(); ++elem_iter) { // Get index of this element in mpVoronoiTessellation unsigned elem_index = elem_iter->GetIndex(); // Get the cell corresponding to this element, via the index of the corresponding node in mrMesh unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index); CellPtr p_cell = this->GetCellUsingLocationIndex(node_index); // Populate the vector of VTK cell data vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this); } mesh_writer.AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // Loop over elements of mpVoronoiTessellation for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin(); elem_iter != mpVoronoiTessellation->GetElementIteratorEnd(); ++elem_iter) { // Get index of this element in mpVoronoiTessellation unsigned elem_index = elem_iter->GetIndex(); // Get the cell corresponding to this element, via the index of the corresponding node in mrMesh unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index); CellPtr p_cell = this->GetCellUsingLocationIndex(node_index); for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]); } } for (unsigned var=0; var<cell_data.size(); var++) { mesh_writer.AddCellData(cell_data_names[var], cell_data[var]); } mesh_writer.WriteVtkUsingMesh(*mpVoronoiTessellation, time.str()); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << ".vtu\"/>\n"; } #endif //CHASTE_VTK }
void NodeBasedCellPopulation<DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK std::stringstream time; time << SimulationTime::Instance()->GetTimeStepsElapsed(); VtkMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results_"+time.str(), false); // Make sure the nodes are ordered contiguously in memory. NodeMap map(1 + this->mpNodesOnlyMesh->GetMaximumNodeIndex()); this->mpNodesOnlyMesh->ReMesh(map); mesh_writer.SetParallelFiles(*mpNodesOnlyMesh); unsigned num_nodes = GetNumNodes(); std::vector<double> cell_types(num_nodes); std::vector<double> cell_ancestors(num_nodes); std::vector<double> cell_mutation_states(num_nodes); std::vector<double> cell_ages(num_nodes); std::vector<double> cell_cycle_phases(num_nodes); std::vector<double> cell_radii(num_nodes); std::vector<std::vector<double> > cellwise_data; std::vector<double> rank(num_nodes); unsigned num_cell_data_items = 0; std::vector<std::string> cell_data_names; // We assume that the first cell is representative of all cells if (num_nodes > 0) { num_cell_data_items = this->Begin()->GetCellData()->GetNumItems(); cell_data_names = this->Begin()->GetCellData()->GetKeys(); } for (unsigned var=0; var<num_cell_data_items; var++) { std::vector<double> cellwise_data_var(num_nodes); cellwise_data.push_back(cellwise_data_var); } // Loop over cells for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin(); cell_iter != this->End(); ++cell_iter) { // Get the node index corresponding to this cell unsigned global_index = this->GetLocationIndexUsingCell(*cell_iter); Node<DIM>* p_node = this->GetNode(global_index); unsigned node_index = this->rGetMesh().SolveNodeMapping(global_index); if (this-> template HasWriter<CellAncestorWriter>()) { double ancestor_index = (cell_iter->GetAncestor() == UNSIGNED_UNSET) ? (-1.0) : (double)cell_iter->GetAncestor(); cell_ancestors[node_index] = ancestor_index; } if (this-> template HasWriter<CellProliferativeTypesWriter>()) { double cell_type = cell_iter->GetCellProliferativeType()->GetColour(); cell_types[node_index] = cell_type; } if (this-> template HasWriter<CellMutationStatesCountWriter>()) { double mutation_state = cell_iter->GetMutationState()->GetColour(); CellPropertyCollection collection = cell_iter->rGetCellPropertyCollection(); CellPropertyCollection label_collection = collection.GetProperties<CellLabel>(); if (label_collection.GetSize() == 1) { boost::shared_ptr<CellLabel> p_label = boost::static_pointer_cast<CellLabel>(label_collection.GetProperty()); mutation_state = p_label->GetColour(); } cell_mutation_states[node_index] = mutation_state; } if (this-> template HasWriter<CellAgesWriter>()) { double age = cell_iter->GetAge(); cell_ages[node_index] = age; } if (this-> template HasWriter<CellProliferativePhasesWriter>()) { double cycle_phase = cell_iter->GetCellCycleModel()->GetCurrentCellCyclePhase(); cell_cycle_phases[node_index] = cycle_phase; } if (this-> template HasWriter<CellVolumesWriter>()) { double cell_radius = p_node->GetRadius(); cell_radii[node_index] = cell_radius; } for (unsigned var=0; var<num_cell_data_items; var++) { cellwise_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]); } rank[node_index] = (PetscTools::GetMyRank()); } mesh_writer.AddPointData("Process rank", rank); if (this-> template HasWriter<CellProliferativeTypesWriter>()) { mesh_writer.AddPointData("Cell types", cell_types); } if (this-> template HasWriter<CellAncestorWriter>()) { mesh_writer.AddPointData("Ancestors", cell_ancestors); } if (this-> template HasWriter<CellMutationStatesCountWriter>()) { mesh_writer.AddPointData("Mutation states", cell_mutation_states); } if (this-> template HasWriter<CellAgesWriter>()) { mesh_writer.AddPointData("Ages", cell_ages); } if (this-> template HasWriter<CellProliferativePhasesWriter>()) { mesh_writer.AddPointData("Cycle phases", cell_cycle_phases); } if (this-> template HasWriter<CellVolumesWriter>()) { mesh_writer.AddPointData("Cell radii", cell_radii); } if (num_cell_data_items > 0) { for (unsigned var=0; var<cellwise_data.size(); var++) { mesh_writer.AddPointData(cell_data_names[var], cellwise_data[var]); } } mesh_writer.WriteFilesUsingMesh(*mpNodesOnlyMesh); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed(); *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << SimulationTime::Instance()->GetTimeStepsElapsed(); *(this->mpVtkMetaFile) << ".vtu\"/>\n"; #endif //CHASTE_VTK }
void PottsBasedCellPopulation<DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK unsigned num_timesteps = SimulationTime::Instance()->GetTimeStepsElapsed(); std::stringstream time; time << num_timesteps; // Create mesh writer for VTK output VtkMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results_"+time.str(), false); // Iterate over any cell writers that are present unsigned num_nodes = GetNumNodes(); for (typename std::set<boost::shared_ptr<AbstractCellWriter<DIM, DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_nodes); // Iterate over nodes in the mesh for (typename AbstractMesh<DIM,DIM>::NodeIterator iter = mpPottsMesh->GetNodeIteratorBegin(); iter != mpPottsMesh->GetNodeIteratorEnd(); ++iter) { // Get the index of this node in the mesh and those elements (i.e. cells) that contain this node unsigned node_index = iter->GetIndex(); std::set<unsigned> element_indices = iter->rGetContainingElementIndices(); // If there are no elements associated with this node, then we set the value of any VTK cell data to be -1 at this node... if (element_indices.empty()) { // Populate the vector of VTK cell data vtk_cell_data[node_index] = -1.0; } else { // ... otherwise there should be exactly one element (i.e. cell) containing this node assert(element_indices.size() == 1); unsigned elem_index = *(element_indices.begin()); CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index); // Populate the vector of VTK cell data vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this); } } mesh_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // When outputting any CellData, we assume that the first cell is representative of all cells unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems(); std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys(); std::vector<std::vector<double> > cell_data; for (unsigned var=0; var<num_cell_data_items; var++) { std::vector<double> cell_data_var(num_nodes); cell_data.push_back(cell_data_var); } for (typename AbstractMesh<DIM,DIM>::NodeIterator iter = mpPottsMesh->GetNodeIteratorBegin(); iter != mpPottsMesh->GetNodeIteratorEnd(); ++iter) { // Get the index of this node in the mesh and those elements (i.e. cells) that contain this node unsigned node_index = iter->GetIndex(); std::set<unsigned> element_indices = iter->rGetContainingElementIndices(); // If there are no elements associated with this node, then we set the value of any VTK cell data to be -1 at this node... if (element_indices.empty()) { for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][node_index] = -1.0; } } else { // ... otherwise there should be exactly one element (i.e. cell) containing this node assert(element_indices.size() == 1); unsigned elem_index = *(element_indices.begin()); CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index); for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][node_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]); } } } for (unsigned var=0; var<cell_data.size(); var++) { mesh_writer.AddPointData(cell_data_names[var], cell_data[var]); } /* * The current VTK writer can only write things which inherit from AbstractTetrahedralMeshWriter. * For now, we do an explicit conversion to NodesOnlyMesh. This can be written to VTK then visualized as glyphs. */ NodesOnlyMesh<DIM> temp_mesh; temp_mesh.ConstructNodesWithoutMesh(*mpPottsMesh, 1.5); // This cut-off is arbitrary, as node connectivity is not used here mesh_writer.WriteFilesUsingMesh(temp_mesh); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << ".vtu\"/>\n"; #endif //CHASTE_VTK }
void TestTessellationConstructor() throw (Exception) { // Create a simple Cylindrical2dMesh, the Delaunay triangulation unsigned cells_across = 3; unsigned cells_up = 3; unsigned thickness_of_ghost_layer = 0; CylindricalHoneycombMeshGenerator generator(cells_across, cells_up, thickness_of_ghost_layer); Cylindrical2dMesh* p_delaunay_mesh = generator.GetCylindricalMesh(); TrianglesMeshWriter<2,2> mesh_writer("TestVertexMeshWriters", "DelaunayMesh", false); TS_ASSERT_THROWS_NOTHING(mesh_writer.WriteFilesUsingMesh(*p_delaunay_mesh)); TS_ASSERT_EQUALS(p_delaunay_mesh->GetWidth(0), 3u); TS_ASSERT_EQUALS(p_delaunay_mesh->CheckIsVoronoi(), true); TS_ASSERT_EQUALS(p_delaunay_mesh->GetNumElements(), 12u); TS_ASSERT_EQUALS(p_delaunay_mesh->GetNumNodes(), 9u); // Create a vertex mesh, the Voronoi tessellation, using the tetrahedral mesh Cylindrical2dVertexMesh voronoi_mesh(*p_delaunay_mesh); VertexMeshWriter<2,2> vertexmesh_writer("TestVertexMeshWriters", "VertexMesh", false); TS_ASSERT_THROWS_NOTHING(vertexmesh_writer.WriteFilesUsingMesh(voronoi_mesh)); // Test the Voronoi tessellation has the correct number of nodes and elements TS_ASSERT_EQUALS(voronoi_mesh.GetWidth(0), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetNumElements(), 9u); TS_ASSERT_EQUALS(voronoi_mesh.GetNumNodes(), 12u); // // Test the location of the Voronoi nodes /* These are ordered from right to left from bottom to top as * 10 1 0 5 4 6 9 2 3 11 7 8 * Due to the numbering of the elements in the generator. */ TS_ASSERT_DELTA(voronoi_mesh.GetNode(10)->rGetLocation()[0], 3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(10)->rGetLocation()[1], sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(1)->rGetLocation()[0], 0.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(1)->rGetLocation()[1], sqrt(3.0)/6.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(0)->rGetLocation()[0], 1.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(0)->rGetLocation()[1], sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(5)->rGetLocation()[0], 1.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(5)->rGetLocation()[1], sqrt(3.0)/6.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(4)->rGetLocation()[0], 2.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(4)->rGetLocation()[1], sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(6)->rGetLocation()[0], 2.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(6)->rGetLocation()[1], sqrt(3.0)/6.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(9)->rGetLocation()[0], 0.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(9)->rGetLocation()[1], 2.0*sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(2)->rGetLocation()[0], 0.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(2)->rGetLocation()[1], 5.0*sqrt(3.0)/6.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(3)->rGetLocation()[0], 1.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(3)->rGetLocation()[1], 2.0*sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(11)->rGetLocation()[0], 1.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(11)->rGetLocation()[1], 5.0*sqrt(3.0)/6.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(7)->rGetLocation()[0], 2.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(7)->rGetLocation()[1], 2.0*sqrt(3.0)/3.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(8)->rGetLocation()[0], 2.5, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetNode(8)->rGetLocation()[1], 5.0*sqrt(3.0)/6.0, 1e-6); // Test the number of nodes owned by each Voronoi element TS_ASSERT_EQUALS(voronoi_mesh.GetElement(0)->GetNumNodes(), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(1)->GetNumNodes(), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(2)->GetNumNodes(), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(3)->GetNumNodes(), 6u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(4)->GetNumNodes(), 6u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(5)->GetNumNodes(), 6u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(6)->GetNumNodes(), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(7)->GetNumNodes(), 3u); TS_ASSERT_EQUALS(voronoi_mesh.GetElement(8)->GetNumNodes(), 3u); // Test element areas TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(0), sqrt(3.0)/12.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(1), sqrt(3.0)/12.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(2), sqrt(3.0)/12.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(3), sqrt(3.0)/2.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(4), sqrt(3.0)/2.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(5), sqrt(3.0)/2.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(6), sqrt(3.0)/12.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(7), sqrt(3.0)/12.0, 1e-6); TS_ASSERT_DELTA(voronoi_mesh.GetVolumeOfElement(8), sqrt(3.0)/12.0, 1e-6); }
void VtkNonlinearElasticitySolutionWriter<DIM>::Write() { if (mpSolver->mOutputDirectory=="") { EXCEPTION("No output directory was given to the mechanics solver"); } #ifdef CHASTE_VTK VtkMeshWriter<DIM, DIM> mesh_writer(mpSolver->mOutputDirectory + "/vtk", "solution", true); // write the displacement std::vector<c_vector<double,DIM> > displacement(mpSolver->mrQuadMesh.GetNumNodes()); std::vector<c_vector<double,DIM> >& r_spatial_solution = mpSolver->rGetSpatialSolution(); for(unsigned i=0; i<mpSolver->mrQuadMesh.GetNumNodes(); i++) { for(unsigned j=0; j<DIM; j++) { displacement[i](j) = r_spatial_solution[i](j)- mpSolver->mrQuadMesh.GetNode(i)->rGetLocation()[j]; } } mesh_writer.AddPointData("Displacement", displacement); // write pressures if (mpSolver->mCompressibilityType==INCOMPRESSIBLE) { mesh_writer.AddPointData("Pressure", mpSolver->rGetPressures()); } // write the element attribute as cell data. std::vector<double> element_attribute; for(typename QuadraticMesh<DIM>::ElementIterator iter = mpSolver->mrQuadMesh.GetElementIteratorBegin(); iter != mpSolver->mrQuadMesh.GetElementIteratorEnd(); ++iter) { element_attribute.push_back(iter->GetAttribute()); } mesh_writer.AddCellData("Attribute", element_attribute); // write strains if requested if (mWriteElementWiseStrains) { mTensorData.clear(); mTensorData.resize(mpSolver->mrQuadMesh.GetNumElements()); std::string name; switch(mElementWiseStrainType) { case DEFORMATION_GRADIENT_F: { name = "deformation_gradient_F"; break; } case DEFORMATION_TENSOR_C: { name = "deformation_tensor_C"; break; } case LAGRANGE_STRAIN_E: { name = "Lagrange_strain_E"; break; } default: { NEVER_REACHED; } } for (typename AbstractTetrahedralMesh<DIM,DIM>::ElementIterator iter = mpSolver->mrQuadMesh.GetElementIteratorBegin(); iter != mpSolver->mrQuadMesh.GetElementIteratorEnd(); ++iter) { mpSolver->GetElementCentroidStrain(mElementWiseStrainType, *iter, mTensorData[iter->GetIndex()]); } mesh_writer.AddTensorCellData(name, mTensorData); } //// Future.. // if (mWriteNodeWiseStresses) // { // std::vector<c_matrix<double,DIM,DIM> > tensor_data; // // use recoverer // mesh_writer.AddTensorCellData("Stress_NAME_ME", tensor_data); // } // final write mesh_writer.WriteFilesUsingMesh(mpSolver->mrQuadMesh); #endif // CHASTE_VTK }
void VertexBasedCellPopulation<DIM>::WriteVtkResultsToFile(const std::string& rDirectory) { #ifdef CHASTE_VTK // Create mesh writer for VTK output VertexMeshWriter<DIM, DIM> mesh_writer(rDirectory, "results", false); // Iterate over any cell writers that are present unsigned num_cells = this->GetNumAllCells(); for (typename std::vector<boost::shared_ptr<AbstractCellWriter<DIM, DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin(); cell_writer_iter != this->mCellWriters.end(); ++cell_writer_iter) { // Create vector to store VTK cell data std::vector<double> vtk_cell_data(num_cells); // Iterate over vertex elements ///\todo #2512 - replace with loop over cells for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpMutableVertexMesh->GetElementIteratorBegin(); elem_iter != mpMutableVertexMesh->GetElementIteratorEnd(); ++elem_iter) { // Get index of this element in the vertex mesh unsigned elem_index = elem_iter->GetIndex(); // Get the cell corresponding to this element CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index); assert(p_cell); // Populate the vector of VTK cell data vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this); } mesh_writer.AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data); } // When outputting any CellData, we assume that the first cell is representative of all cells unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems(); std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys(); std::vector<std::vector<double> > cell_data; for (unsigned var=0; var<num_cell_data_items; var++) { std::vector<double> cell_data_var(num_cells); cell_data.push_back(cell_data_var); } // Loop over vertex elements ///\todo #2512 - replace with loop over cells for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mpMutableVertexMesh->GetElementIteratorBegin(); elem_iter != mpMutableVertexMesh->GetElementIteratorEnd(); ++elem_iter) { // Get index of this element in the vertex mesh unsigned elem_index = elem_iter->GetIndex(); // Get the cell corresponding to this element CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index); assert(p_cell); for (unsigned var=0; var<num_cell_data_items; var++) { cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]); } } for (unsigned var=0; var<num_cell_data_items; var++) { mesh_writer.AddCellData(cell_data_names[var], cell_data[var]); } unsigned num_timesteps = SimulationTime::Instance()->GetTimeStepsElapsed(); std::stringstream time; time << num_timesteps; mesh_writer.WriteVtkUsingMesh(*mpMutableVertexMesh, time.str()); *(this->mpVtkMetaFile) << " <DataSet timestep=\""; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_"; *(this->mpVtkMetaFile) << num_timesteps; *(this->mpVtkMetaFile) << ".vtu\"/>\n"; #endif //CHASTE_VTK }