36 #include "VertexBasedCellPopulation.hpp"
37 #include "Warnings.hpp"
38 #include "ShortAxisVertexBasedDivisionRule.hpp"
39 #include "StepSizeException.hpp"
40 #include "WildTypeCellMutationState.hpp"
41 #include "Cylindrical2dVertexMesh.hpp"
43 #include "T2SwapCellKiller.hpp"
44 #include "ApoptoticCellProperty.hpp"
45 #include "CellPopulationElementWriter.hpp"
46 #include "VertexT1SwapLocationsWriter.hpp"
47 #include "VertexT2SwapLocationsWriter.hpp"
48 #include "VertexT3SwapLocationsWriter.hpp"
49 #include "AbstractCellBasedSimulation.hpp"
51 template<
unsigned DIM>
53 std::vector<CellPtr>& rCells,
56 const std::vector<unsigned> locationIndices)
58 mDeleteMesh(deleteMesh),
59 mOutputCellRearrangementLocations(true),
60 mRestrictVertexMovement(true)
66 std::list<CellPtr>::iterator it = this->
mCells.begin();
67 for (
unsigned i=0; it != this->
mCells.end(); ++it, ++i)
69 unsigned index = locationIndices.empty() ? i : locationIndices[i];
80 template<
unsigned DIM>
84 mOutputCellRearrangementLocations(true),
85 mRestrictVertexMovement(true)
90 template<
unsigned DIM>
99 template<
unsigned DIM>
103 double average_damping_constant = 0.0;
105 std::set<unsigned> containing_elements = GetNode(nodeIndex)->rGetContainingElementIndices();
107 unsigned num_containing_elements = containing_elements.size();
108 if (num_containing_elements == 0)
110 EXCEPTION(
"At time " <<
SimulationTime::Instance()->GetTime() <<
", Node " << nodeIndex <<
" is not contained in any elements, so GetDampingConstant() returns zero");
113 double temp = 1.0/((
double) num_containing_elements);
114 for (std::set<unsigned>::iterator iter = containing_elements.begin();
115 iter != containing_elements.end();
118 CellPtr p_cell = this->GetCellUsingLocationIndex(*iter);
121 if (cell_is_wild_type)
123 average_damping_constant += this->GetDampingConstantNormal()*temp;
127 average_damping_constant += this->GetDampingConstantMutant()*temp;
131 return average_damping_constant;
134 template<
unsigned DIM>
137 return *mpMutableVertexMesh;
140 template<
unsigned DIM>
143 return *mpMutableVertexMesh;
146 template<
unsigned DIM>
149 return mpMutableVertexMesh->GetElement(elementIndex);
152 template<
unsigned DIM>
155 return this->mrMesh.GetNumNodes();
158 template<
unsigned DIM>
161 return mpMutableVertexMesh->GetCentroidOfElement(this->mCellLocationMap[pCell.get()]);
164 template<
unsigned DIM>
167 return this->mrMesh.GetNode(index);
170 template<
unsigned DIM>
173 unsigned elem_index = this->GetLocationIndexUsingCell(pCell);
174 return this->rGetMesh().GetNeighbouringElementIndices(elem_index);
177 template<
unsigned DIM>
180 return mpMutableVertexMesh->AddNode(pNewNode);
183 template<
unsigned DIM>
186 mpMutableVertexMesh->SetNode(nodeIndex, rNewLocation);
189 template<
unsigned DIM>
192 return mpMutableVertexMesh->GetElement(this->GetLocationIndexUsingCell(pCell));
195 template<
unsigned DIM>
198 return mpMutableVertexMesh->GetNumElements();
201 template<
unsigned DIM>
208 c_vector<double, DIM> division_vector = mpVertexBasedDivisionRule->CalculateCellDivisionVector(pParentCell, *
this);
211 unsigned new_element_index = mpMutableVertexMesh->DivideElementAlongGivenAxis(p_element, division_vector,
true);
214 this->mCells.push_back(pNewCell);
217 CellPtr p_created_cell = this->mCells.back();
218 this->SetCellUsingLocationIndex(new_element_index,p_created_cell);
219 this->mCellLocationMap[p_created_cell.get()] = new_element_index;
221 return p_created_cell;
224 template<
unsigned DIM>
227 unsigned num_removed = 0;
229 for (std::list<CellPtr>::iterator it = this->mCells.begin();
230 it != this->mCells.end();
240 if (!(this->GetElement(this->GetLocationIndexUsingCell((*it)))->IsDeleted()))
244 WARN_ONCE_ONLY(
"A Cell is removed without performing a T2 swap. This could leave a void in the mesh.");
245 mpMutableVertexMesh->DeleteElementPriorToReMesh(this->GetLocationIndexUsingCell((*it)));
249 it = this->mCells.erase(it);
259 template<
unsigned DIM>
262 double length = norm_2(rDisplacement);
264 if(mRestrictVertexMovement)
266 if (length > 0.5*mpMutableVertexMesh->GetCellRearrangementThreshold())
268 rDisplacement *= 0.5*mpMutableVertexMesh->GetCellRearrangementThreshold()/length;
270 std::ostringstream message;
271 message <<
"Vertices are moving more than half the CellRearrangementThreshold. This could cause elements to become inverted ";
272 message <<
"so the motion has been restricted. Use a smaller timestep to avoid these warnings.";
274 double suggested_step = 0.95*dt*((0.5*mpMutableVertexMesh->GetCellRearrangementThreshold())/length);
281 template<
unsigned DIM>
284 return GetElementCorrespondingToCell(pCell)->IsDeleted();
287 template<
unsigned DIM>
291 mpMutableVertexMesh->ReMesh(element_map);
293 if (!element_map.IsIdentityMap())
297 std::map<Cell*, unsigned> old_map = this->mCellLocationMap;
299 this->mCellLocationMap.clear();
300 this->mLocationCellMap.clear();
302 for (std::list<CellPtr>::iterator cell_iter = this->mCells.begin();
303 cell_iter != this->mCells.end();
307 unsigned old_elem_index = old_map[(*cell_iter).get()];
308 assert(!element_map.IsDeleted(old_elem_index));
310 unsigned new_elem_index = element_map.
GetNewIndex(old_elem_index);
311 this->SetCellUsingLocationIndex(new_elem_index, *cell_iter);
318 element_map.ResetToIdentity();
321 template<
unsigned DIM>
325 std::vector<unsigned> validated_element = std::vector<unsigned>(this->GetNumElements(), 0);
327 cell_iter != this->End();
330 unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
331 validated_element[elem_index]++;
334 for (
unsigned i=0; i<validated_element.size(); i++)
336 if (validated_element[i] == 0)
341 if (validated_element[i] > 1)
344 EXCEPTION(
"At time " <<
SimulationTime::Instance()->GetTime() <<
", Element " << i <<
" appears to have " << validated_element[i] <<
" cells associated with it");
349 template<
unsigned DIM>
352 pPopulationWriter->Visit(
this);
355 template<
unsigned DIM>
358 pPopulationCountWriter->Visit(
this);
361 template<
unsigned DIM>
364 pCellWriter->VisitCell(pCell,
this);
367 template<
unsigned DIM>
371 unsigned elem_index = this->GetLocationIndexUsingCell(pCell);
374 unsigned rosette_rank = mpMutableVertexMesh->GetRosetteRankOfElement(elem_index);
379 template<
unsigned DIM>
383 unsigned elem_index = this->GetLocationIndexUsingCell(pCell);
386 double cell_volume = mpMutableVertexMesh->GetVolumeOfElement(elem_index);
391 template<
unsigned DIM>
400 unsigned num_cells = this->GetNumAllCells();
402 cell_writer_iter != this->mCellWriters.end();
406 std::vector<double> vtk_cell_data(num_cells);
410 elem_iter != mpMutableVertexMesh->GetElementIteratorEnd();
414 unsigned elem_index = elem_iter->GetIndex();
417 CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index);
421 vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell,
this);
424 mesh_writer.
AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
428 unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems();
429 std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys();
431 std::vector<std::vector<double> > cell_data;
432 for (
unsigned var=0; var<num_cell_data_items; var++)
434 std::vector<double> cell_data_var(num_cells);
435 cell_data.push_back(cell_data_var);
440 elem_iter != mpMutableVertexMesh->GetElementIteratorEnd();
444 unsigned elem_index = elem_iter->GetIndex();
447 CellPtr p_cell = this->GetCellUsingLocationIndex(elem_index);
450 for (
unsigned var=0; var<num_cell_data_items; var++)
452 cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]);
455 for (
unsigned var=0; var<num_cell_data_items; var++)
457 mesh_writer.
AddCellData(cell_data_names[var], cell_data[var]);
461 std::stringstream time;
462 time << num_timesteps;
466 *(this->mpVtkMetaFile) <<
" <DataSet timestep=\"";
467 *(this->mpVtkMetaFile) << num_timesteps;
468 *(this->mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"results_";
469 *(this->mpVtkMetaFile) << num_timesteps;
470 *(this->mpVtkMetaFile) <<
".vtu\"/>\n";
474 template<
unsigned DIM>
477 if (this->mOutputResultsForChasteVisualizer)
479 if (!this->
template HasWriter<CellPopulationElementWriter>())
481 this->
template AddPopulationWriter<CellPopulationElementWriter>();
485 if (mOutputCellRearrangementLocations)
487 if (!this->
template HasWriter<VertexT1SwapLocationsWriter>())
489 this->
template AddPopulationWriter<VertexT1SwapLocationsWriter>();
491 if (!this->
template HasWriter<VertexT2SwapLocationsWriter>())
493 this->
template AddPopulationWriter<VertexT2SwapLocationsWriter>();
495 if (!this->
template HasWriter<VertexT3SwapLocationsWriter>())
497 this->
template AddPopulationWriter<VertexT3SwapLocationsWriter>();
504 template<
unsigned DIM>
507 return mOutputCellRearrangementLocations;
510 template<
unsigned DIM>
513 mOutputCellRearrangementLocations = outputCellRearrangementLocations;
516 template<
unsigned DIM>
519 *rParamsFile <<
"\t\t<CellRearrangementThreshold>" << mpMutableVertexMesh->GetCellRearrangementThreshold() <<
"</CellRearrangementThreshold>\n";
520 *rParamsFile <<
"\t\t<T2Threshold>" << mpMutableVertexMesh->GetT2Threshold() <<
"</T2Threshold>\n";
521 *rParamsFile <<
"\t\t<CellRearrangementRatio>" << mpMutableVertexMesh->GetCellRearrangementRatio() <<
"</CellRearrangementRatio>\n";
522 *rParamsFile <<
"\t\t<OutputCellRearrangementLocations>" << mOutputCellRearrangementLocations <<
"</OutputCellRearrangementLocations>\n";
525 *rParamsFile <<
"\t\t<VertexBasedDivisionRule>\n";
526 mpVertexBasedDivisionRule->OutputCellVertexBasedDivisionRuleInfo(rParamsFile);
527 *rParamsFile <<
"\t\t</VertexBasedDivisionRule>\n";
533 template<
unsigned DIM>
537 double width = this->mrMesh.GetWidth(rDimension);
542 template<
unsigned DIM>
545 return mpMutableVertexMesh->GetNeighbouringNodeIndices(index);
548 template<
unsigned DIM>
551 return mpVertexBasedDivisionRule;
554 template<
unsigned DIM>
557 mpVertexBasedDivisionRule = pVertexBasedDivisionRule;
560 template<
unsigned DIM>
563 return mLocationsOfT2Swaps;
566 template<
unsigned DIM>
569 return mCellIdsOfT2Swaps;
572 template<
unsigned DIM>
575 mLocationsOfT2Swaps.push_back(locationOfT2Swap);
578 template<
unsigned DIM>
581 mCellIdsOfT2Swaps.push_back(idOfT2Swap);
584 template<
unsigned DIM>
587 mCellIdsOfT2Swaps.clear();
588 mLocationsOfT2Swaps.clear();
591 template<
unsigned DIM>
598 unsigned num_vertex_nodes = mpMutableVertexMesh->GetNumNodes();
599 unsigned num_vertex_elements = mpMutableVertexMesh->GetNumElements();
601 std::string mesh_file_name =
"mesh";
604 std::stringstream pid;
606 OutputFileHandler output_file_handler(
"2D_temporary_tetrahedral_mesh_" + pid.str());
610 unsigned num_tetrahedral_nodes = num_vertex_nodes + num_vertex_elements;
613 out_stream p_node_file = output_file_handler.OpenOutputFile(mesh_file_name+
".node");
614 (*p_node_file) << std::scientific;
615 (*p_node_file) << std::setprecision(20);
616 (*p_node_file) << num_tetrahedral_nodes <<
"\t2\t0\t1" << std::endl;
619 for (
unsigned node_index=0; node_index<num_vertex_nodes; node_index++)
621 Node<DIM>* p_node = mpMutableVertexMesh->GetNode(node_index);
624 unsigned index = p_node->
GetIndex();
625 const c_vector<double, DIM>& r_location = p_node->
rGetLocation();
628 (*p_node_file) << index <<
"\t" << r_location[0] <<
"\t" << r_location[1] <<
"\t" << is_boundary_node << std::endl;
632 unsigned num_tetrahedral_elements = 0;
633 for (
unsigned vertex_elem_index=0; vertex_elem_index<num_vertex_elements; vertex_elem_index++)
635 unsigned index = num_vertex_nodes + vertex_elem_index;
637 c_vector<double, DIM> location = mpMutableVertexMesh->GetCentroidOfElement(vertex_elem_index);
640 unsigned is_boundary_node = 0;
641 (*p_node_file) << index <<
"\t" << location[0] <<
"\t" << location[1] <<
"\t" << is_boundary_node << std::endl;
644 num_tetrahedral_elements += mpMutableVertexMesh->GetElement(vertex_elem_index)->GetNumNodes();
646 p_node_file->close();
649 out_stream p_elem_file = output_file_handler.OpenOutputFile(mesh_file_name+
".ele");
650 (*p_elem_file) << std::scientific;
651 (*p_elem_file) << num_tetrahedral_elements <<
"\t3\t0" << std::endl;
653 std::set<std::pair<unsigned, unsigned> > tetrahedral_edges;
655 unsigned tetrahedral_elem_index = 0;
656 for (
unsigned vertex_elem_index=0; vertex_elem_index<num_vertex_elements; vertex_elem_index++)
661 unsigned num_nodes_in_vertex_element = p_vertex_element->
GetNumNodes();
662 for (
unsigned local_index=0; local_index<num_nodes_in_vertex_element; local_index++)
665 unsigned node_1_index = p_vertex_element->
GetNodeGlobalIndex((local_index+1)%num_nodes_in_vertex_element);
666 unsigned node_2_index = num_vertex_nodes + vertex_elem_index;
668 (*p_elem_file) << tetrahedral_elem_index++ <<
"\t" << node_0_index <<
"\t" << node_1_index <<
"\t" << node_2_index << std::endl;
671 std::pair<unsigned, unsigned> edge_0 = this->CreateOrderedPair(node_0_index, node_1_index);
672 std::pair<unsigned, unsigned> edge_1 = this->CreateOrderedPair(node_1_index, node_2_index);
673 std::pair<unsigned, unsigned> edge_2 = this->CreateOrderedPair(node_2_index, node_0_index);
675 tetrahedral_edges.insert(edge_0);
676 tetrahedral_edges.insert(edge_1);
677 tetrahedral_edges.insert(edge_2);
680 p_elem_file->close();
683 out_stream p_edge_file = output_file_handler.OpenOutputFile(mesh_file_name+
".edge");
684 (*p_edge_file) << std::scientific;
685 (*p_edge_file) << tetrahedral_edges.size() <<
"\t1" << std::endl;
687 unsigned edge_index = 0;
688 for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = tetrahedral_edges.begin();
689 edge_iter != tetrahedral_edges.end();
692 std::pair<unsigned, unsigned> this_edge = *edge_iter;
695 bool is_boundary_edge =
false;
696 if (this_edge.first < mpMutableVertexMesh->GetNumNodes() &&
697 this_edge.second < mpMutableVertexMesh->GetNumNodes())
699 is_boundary_edge = (mpMutableVertexMesh->GetNode(this_edge.first)->IsBoundaryNode() &&
700 mpMutableVertexMesh->GetNode(this_edge.second)->IsBoundaryNode() );
702 unsigned is_boundary_edge_unsigned = is_boundary_edge ? 1 : 0;
704 (*p_edge_file) << edge_index++ <<
"\t" << this_edge.first <<
"\t" << this_edge.second <<
"\t" << is_boundary_edge_unsigned << std::endl;
706 p_edge_file->close();
718 output_file_handler.FindFile(
"").Remove();
726 template<
unsigned DIM>
729 bool non_apoptotic_cell_present =
true;
731 if (pdeNodeIndex < this->GetNumNodes())
733 std::set<unsigned> containing_element_indices = this->GetNode(pdeNodeIndex)->rGetContainingElementIndices();
735 for (std::set<unsigned>::iterator iter = containing_element_indices.begin();
736 iter != containing_element_indices.end();
739 if (this->GetCellUsingLocationIndex(*iter)->template HasCellProperty<ApoptoticCellProperty>() )
741 non_apoptotic_cell_present =
false;
752 non_apoptotic_cell_present = !(this->GetCellUsingLocationIndex(pdeNodeIndex - this->GetNumNodes())->template HasCellProperty<ApoptoticCellProperty>());
755 return non_apoptotic_cell_present;
758 template<
unsigned DIM>
760 unsigned pdeNodeIndex,
761 std::string& rVariableName,
762 bool dirichletBoundaryConditionApplies,
763 double dirichletBoundaryValue)
765 unsigned num_nodes = this->GetNumNodes();
770 if (pdeNodeIndex >= num_nodes)
773 assert(pdeNodeIndex-num_nodes < num_nodes);
775 CellPtr p_cell = this->GetCellUsingLocationIndex(pdeNodeIndex - num_nodes);
776 value = p_cell->GetCellData()->GetItem(rVariableName);
781 if (dirichletBoundaryConditionApplies)
784 value = dirichletBoundaryValue;
788 assert(pdeNodeIndex < num_nodes);
789 Node<DIM>* p_node = this->GetNode(pdeNodeIndex);
793 for (std::set<unsigned>::iterator index_iter = containing_elements.begin();
794 index_iter != containing_elements.end();
797 assert(*index_iter < num_nodes);
798 CellPtr p_cell = this->GetCellUsingLocationIndex(*index_iter);
799 value += p_cell->GetCellData()->GetItem(rVariableName);
801 value /= containing_elements.size();
808 template<
unsigned DIM>
814 template<
unsigned DIM>
817 if (
bool(dynamic_cast<Cylindrical2dVertexMesh*>(&(this->mrMesh))))
819 *pVizSetupFile <<
"MeshWidth\t" << this->GetWidth(0) <<
"\n";
823 template<
unsigned DIM>
831 template<
unsigned DIM>
834 return mRestrictVertexMovement;
837 template<
unsigned DIM>
840 mRestrictVertexMovement = restrictMovement;
void SetOutputCellRearrangementLocations(bool outputCellRearrangementLocations)
void AddCellData(std::string dataName, std::vector< double > dataPayload)
std::vector< c_vector< double, DIM > > GetLocationsOfT2Swaps()
virtual double GetDefaultTimeStep()
void AddCellKiller(boost::shared_ptr< AbstractCellKiller< SPACE_DIM > > pCellKiller)
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< DIM, DIM > > pPopulationCountWriter)
double GetVolumeOfCell(CellPtr pCell)
virtual ~VertexBasedCellPopulation()
unsigned GetNodeGlobalIndex(unsigned localIndex) const
virtual void SimulationSetupHook(AbstractCellBasedSimulation< DIM, DIM > *pSimulation)
unsigned GetNumElements()
bool IsBoundaryNode() const
#define EXCEPTION(message)
static SimulationTime * Instance()
boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > mpVertexBasedDivisionRule
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< DIM, DIM > > pCellWriter, CellPtr pCell)
void SetVertexBasedDivisionRule(boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > pVertexBasedDivisionRule)
std::vector< unsigned > GetCellIdsOfT2Swaps()
virtual bool IsPdeNodeAssociatedWithNonApoptoticCell(unsigned pdeNodeIndex)
std::set< unsigned > & rGetContainingElementIndices()
virtual void WriteDataToVisualizerSetupFile(out_stream &pVizSetupFile)
unsigned GetTimeStepsElapsed() const
std::set< unsigned > GetNeighbouringNodeIndices(unsigned index)
std::string GetOutputDirectoryFullPath() const
boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > GetVertexBasedDivisionRule()
bool IsCellAssociatedWithADeletedLocation(CellPtr pCell)
double GetDampingConstant(unsigned nodeIndex)
void SetRestrictVertexMovementBoolean(bool restrictVertexMovement)
std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
unsigned GetRosetteRankOfCell(CellPtr pCell)
MutableVertexMesh< DIM, DIM > & rGetMesh()
bool GetRestrictVertexMovementBoolean()
VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< DIM, DIM > > pPopulationWriter)
void Update(bool hasHadBirthsOrDeaths=true)
void AddLocationOfT2Swap(c_vector< double, DIM > locationOfT2Swap)
VertexBasedCellPopulation(MutableVertexMesh< DIM, DIM > &rMesh, std::vector< CellPtr > &rCells, bool deleteMesh=false, bool validate=true, const std::vector< unsigned > locationIndices=std::vector< unsigned >())
Node< DIM > * GetNode(unsigned index)
unsigned GetNumNodes() const
virtual TetrahedralMesh< DIM, DIM > * GetTetrahedralMeshForPdeModifier()
void WriteVtkUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::string stamp="")
virtual void CheckForStepSizeException(unsigned nodeIndex, c_vector< double, DIM > &rDisplacement, double dt)
unsigned GetNewIndex(unsigned oldIndex) const
void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
unsigned RemoveDeadCells()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
std::list< CellPtr > mCells
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
void SetMeshHasChangedSinceLoading()
void SetNode(unsigned index, ChastePoint< DIM > &rNewLocation)
const c_vector< double, SPACE_DIM > & rGetLocation() const
void AddCellIdOfT2Swap(unsigned idOfT2Swap)
double GetWidth(const unsigned &rDimension)
c_vector< double, DIM > GetLocationOfCellCentre(CellPtr pCell)
unsigned AddNode(Node< DIM > *pNewNode)
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
MutableVertexMesh< DIM, DIM > * mpMutableVertexMesh
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
virtual double GetCellDataItemAtPdeNode(unsigned pdeNodeIndex, std::string &rVariableName, bool dirichletBoundaryConditionApplies=false, double dirichletBoundaryValue=0.0)
unsigned GetIndex() const
void ClearLocationsAndCellIdsOfT2Swaps()
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
VertexElement< DIM, DIM > * GetElement(unsigned elementIndex)
#define MAKE_PTR_ARGS(TYPE, NAME, ARGS)
bool GetOutputCellRearrangementLocations()
VertexElement< DIM, DIM > * GetElementCorrespondingToCell(CellPtr pCell)