36 #include <boost/lexical_cast.hpp> 37 #define _BACKWARD_BACKWARD_WARNING_H 1 //Cut out the vtk deprecated warning 38 #include <vtkIdList.h> 39 #include <vtkCellArray.h> 41 #include <vtkPoints.h> 42 #include <vtkTriangle.h> 43 #include <vtkPoints.h> 45 #include <vtkGenericCell.h> 46 #include "Exception.hpp" 47 #include "Warnings.hpp" 49 #include "Polygon.hpp" 50 #include "DiscreteContinuumMesh.hpp" 51 #include "Element.hpp" 52 #include "UblasVectorInclude.hpp" 53 #include "AbstractTetrahedralMesh.hpp" 54 #include "VtkMeshWriter.hpp" 55 #include "BaseUnits.hpp" 57 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
60 mReferenceLength(
BaseUnits::Instance()->GetReferenceLengthScale()),
62 mpVtkCellLocator(vtkSmartPointer<vtkCellLocator>::New()),
63 mVtkRepresentationUpToDate(false),
69 mCellPopulationReferenceLength(
BaseUnits::Instance()->GetReferenceLengthScale())
74 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
81 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
87 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
93 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
98 mpVtkMesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
99 vtkSmartPointer<vtkPoints> p_vtk_points = vtkSmartPointer<vtkPoints>::New();
100 std::vector<c_vector<double, SPACE_DIM> > node_locations =
GetNodeLocations();
101 p_vtk_points->SetNumberOfPoints(node_locations.size());
102 for(
unsigned idx=0; idx<node_locations.size(); idx++)
106 p_vtk_points->InsertPoint(idx, node_locations[idx][0], node_locations[idx][1], node_locations[idx][2]);
110 p_vtk_points->InsertPoint(idx, node_locations[idx][0], node_locations[idx][1], 0.0);
116 std::vector<std::vector<unsigned> > element_connectivity =
GetConnectivity();
117 unsigned num_elements = element_connectivity.size();
118 mpVtkMesh->Allocate(num_elements, num_elements);
120 for(
unsigned idx=0; idx<num_elements; idx++)
124 vtkSmartPointer<vtkTetra> p_vtk_element = vtkSmartPointer<vtkTetra>::New();
125 unsigned num_nodes = element_connectivity[idx].size();
126 for(
unsigned jdx=0; jdx<num_nodes; jdx++)
128 p_vtk_element->GetPointIds()->SetId(jdx, element_connectivity[idx][jdx]);
130 mpVtkMesh->InsertNextCell(p_vtk_element->GetCellType(), p_vtk_element->GetPointIds());
134 vtkSmartPointer<vtkTriangle> p_vtk_element = vtkSmartPointer<vtkTriangle>::New();
135 unsigned num_nodes = element_connectivity[idx].size();
136 for(
unsigned jdx=0; jdx<num_nodes; jdx++)
138 p_vtk_element->GetPointIds()->SetId(jdx, element_connectivity[idx][jdx]);
140 mpVtkMesh->InsertNextCell(p_vtk_element->GetCellType(), p_vtk_element->GetPointIds());
152 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
158 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
161 std::vector<c_vector<double, SPACE_DIM> > centroids(this->GetNumElements());
162 for(
unsigned idx=0; idx<this->GetNumElements(); idx++)
164 centroids[idx] = this->GetElement(idx)->CalculateCentroid();
169 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
178 mPointElementMap = std::vector<std::vector<unsigned> >(this->GetNumElements());
180 std::vector<int> cell_indices(points.size());
181 for(
unsigned idx=0; idx<points.size(); idx++)
206 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
221 EXCEPTION(
"A cell population has not been set. Can not create a cell element map.");
226 mCellElementMap = std::vector<std::vector<CellPtr> >(this->GetNumElements());
229 for (
typename AbstractCellPopulation<SPACE_DIM>::Iterator cell_iter =
mpCellPopulation->Begin();
232 c_vector<double, SPACE_DIM> location =
mpCellPopulation->GetLocationOfCellCentre(*cell_iter);
234 x_coords[0] = location[0]*cell_mesh_length_scaling;
235 x_coords[1] = location[1]*cell_mesh_length_scaling;
238 x_coords[2] = location[2]*cell_mesh_length_scaling;
255 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
257 bool useVesselSurface)
266 EXCEPTION(
"A vessel network has not been set. Can not create a vessel element map.");
270 unsigned num_elements = this->GetNumElements();
271 mSegmentElementMap = std::vector<std::vector<boost::shared_ptr<VesselSegment<SPACE_DIM> > > >(num_elements);
273 std::vector<boost::shared_ptr<VesselSegment<SPACE_DIM> > > segments =
mpNetwork->GetVesselSegments();
275 for (
unsigned jdx = 0; jdx < segments.size(); jdx++)
302 vtkSmartPointer<vtkIdList> p_id_list = vtkSmartPointer<vtkIdList>::New();
303 mpVtkCellLocator->FindCellsAlongLine(x_coords1, x_coords2, 1.e-8, p_id_list);
304 unsigned num_intersections = p_id_list->GetNumberOfIds();
305 for(
unsigned idx=0; idx<num_intersections; idx++)
314 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
317 std::vector<std::vector<unsigned> > connectivity;
318 unsigned num_elements = AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumElements();
319 for (
unsigned idx = 0; idx < num_elements; idx++)
321 std::vector<unsigned> node_indexes;
322 unsigned num_nodes = AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElement(idx)->GetNumNodes();
323 for (
unsigned jdx = 0; jdx < num_nodes; jdx++)
325 node_indexes.push_back(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetElement(idx)->GetNodeGlobalIndex(jdx));
327 connectivity.push_back(node_indexes);
332 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
335 unsigned num_nodes = AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumNodes();
336 std::vector<c_vector<double, SPACE_DIM> > locations(num_nodes);
337 for (
unsigned idx = 0; idx < num_nodes; idx++)
339 locations[idx] = AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNode(idx)->rGetLocation();
344 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
347 unsigned num_nodes = AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::GetNumNodes();
348 std::vector<DimensionalChastePoint<SPACE_DIM> > locations(num_nodes);
349 for (
unsigned idx = 0; idx < num_nodes; idx++)
356 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
358 int *elementList,
unsigned numberOfFaces,
int *faceList,
361 unsigned nodes_per_element = mesherOutput.numberofcorners;
363 assert(nodes_per_element == ELEMENT_DIM + 1 || nodes_per_element == (ELEMENT_DIM + 1) * (ELEMENT_DIM + 2) / 2);
365 for (
unsigned i = 0; i < this->mBoundaryElements.size(); i++)
367 delete this->mBoundaryElements[i];
369 for (
unsigned i = 0; i < this->mElements.size(); i++)
371 delete this->mElements[i];
373 for (
unsigned i = 0; i < this->mNodes.size(); i++)
375 delete this->mNodes[i];
378 this->mNodes.clear();
379 this->mElements.clear();
380 this->mBoundaryElements.clear();
381 this->mBoundaryNodes.clear();
384 for (
unsigned node_index = 0; node_index < (unsigned) mesherOutput.numberofpoints; node_index++)
386 this->mNodes.push_back(
new Node<SPACE_DIM>(node_index, &mesherOutput.pointlist[node_index * SPACE_DIM],
false));
390 this->mElements.reserve(numberOfElements);
392 unsigned real_element_index = 0;
393 for (
unsigned element_index = 0; element_index < numberOfElements; element_index++)
395 std::vector<Node<SPACE_DIM>*> nodes;
396 for (
unsigned j = 0; j < ELEMENT_DIM + 1; j++)
398 unsigned global_node_index = elementList[element_index * (nodes_per_element) + j];
399 assert(global_node_index < this->mNodes.size());
400 nodes.push_back(this->mNodes[global_node_index]);
408 Element<ELEMENT_DIM, SPACE_DIM>* p_element;
411 p_element =
new Element<ELEMENT_DIM, SPACE_DIM>(real_element_index, nodes);
414 this->mElements.push_back(p_element);
417 for (
unsigned j = ELEMENT_DIM + 1; j < nodes_per_element; j++)
419 unsigned global_node_index = elementList[element_index * nodes_per_element + j];
420 assert(global_node_index < this->mNodes.size());
421 this->mElements[real_element_index]->AddNode(this->mNodes[global_node_index]);
422 this->mNodes[global_node_index]->AddElement(real_element_index);
423 this->mNodes[global_node_index]->MarkAsInternal();
425 real_element_index++;
431 WARNING(
"Triangle has produced a zero area (collinear) element");
435 WARNING(
"Tetgen has produced a zero volume (coplanar) element");
441 unsigned next_boundary_element_index = 0;
442 for (
unsigned boundary_element_index = 0; boundary_element_index < numberOfFaces; boundary_element_index++)
448 if (edgeMarkerList == NULL || edgeMarkerList[boundary_element_index] == 1)
450 std::vector<Node<SPACE_DIM>*> nodes;
451 for (
unsigned j = 0; j < ELEMENT_DIM; j++)
453 unsigned global_node_index = faceList[boundary_element_index * ELEMENT_DIM + j];
454 assert(global_node_index < this->mNodes.size());
455 nodes.push_back(this->mNodes[global_node_index]);
456 if (!nodes[j]->IsBoundaryNode())
458 nodes[j]->SetAsBoundaryNode();
459 this->mBoundaryNodes.push_back(nodes[j]);
467 BoundaryElement<ELEMENT_DIM - 1, SPACE_DIM>* p_b_element;
470 p_b_element =
new BoundaryElement<ELEMENT_DIM - 1, SPACE_DIM>(next_boundary_element_index, nodes);
471 this->mBoundaryElements.push_back(p_b_element);
472 next_boundary_element_index++;
477 assert(SPACE_DIM == 3);
482 this->RefreshJacobianCachedData();
485 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
491 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
493 units::quantity<unit::length> cellLengthScale)
499 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
vtkSmartPointer< vtkUnstructuredGrid > mpVtkMesh
std::vector< c_vector< double, SPACE_DIM > > GetElementCentroids()
std::vector< c_vector< double, SPACE_DIM > > GetNodeLocations()
std::vector< unsigned > GetElementRegionMarkers()
units::quantity< unit::length > mCellPopulationReferenceLength
std::vector< std::vector< unsigned > > GetConnectivity()
std::vector< std::vector< CellPtr > > mCellElementMap
boost::shared_ptr< VesselNetwork< SPACE_DIM > > mpNetwork
const std::vector< std::vector< CellPtr > > & GetElementCellMap(bool update=true)
std::vector< std::vector< boost::shared_ptr< VesselSegment< SPACE_DIM > > > > mSegmentElementMap
std::vector< std::vector< boost::shared_ptr< VesselSegment< SPACE_DIM > > > > GetElementSegmentMap(bool update=true, bool useVesselSurface=false)
void ImportDiscreteContinuumMeshFromTetgen(tetgen::tetgenio &mesherOutput, unsigned numberOfElements, int *elementList, unsigned numberOfFaces, int *faceList, int *edgeMarkerList)
vtkSmartPointer< vtkUnstructuredGrid > GetAsVtkUnstructuredGrid()
units::quantity< unit::length > mReferenceLength
c_vector< double, DIM > GetLocation(units::quantity< unit::length > scale)
std::vector< std::vector< unsigned > > GetPointElementMap(std::vector< DimensionalChastePoint< SPACE_DIM > > points)
void SetCellPopulation(AbstractCellPopulation< SPACE_DIM > &rCellPopulation, units::quantity< unit::length > cellLengthScale)
vtkSmartPointer< vtkCellLocator > mpVtkCellLocator
std::vector< DimensionalChastePoint< SPACE_DIM > > GetNodeLocationsAsPoints()
void SetAttributes(std::vector< unsigned > attributes)
units::quantity< unit::length > GetReferenceLengthScale()
static boost::shared_ptr< DiscreteContinuumMesh< ELEMENT_DIM, SPACE_DIM > > Create()
void SetVesselNetwork(boost::shared_ptr< VesselNetwork< SPACE_DIM > > pNetwork)
std::vector< std::vector< unsigned > > mPointElementMap
std::vector< unsigned > mAttributes
bool mVtkRepresentationUpToDate
AbstractCellPopulation< SPACE_DIM > * mpCellPopulation