void OffLatticeSimulation<ELEMENT_DIM,SPACE_DIM>::UpdateCellLocationsAndTopology() { // Calculate forces CellBasedEventHandler::BeginEvent(CellBasedEventHandler::FORCE); // Clear all forces for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->mrCellPopulation.rGetMesh().GetNodeIteratorBegin(); node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd(); ++node_iter) { node_iter->ClearAppliedForce(); } // Now add force contributions from each AbstractForce for (typename std::vector<boost::shared_ptr<AbstractForce<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mForceCollection.begin(); iter != mForceCollection.end(); ++iter) { (*iter)->AddForceContribution(this->mrCellPopulation); } CellBasedEventHandler::EndEvent(CellBasedEventHandler::FORCE); // Update node positions CellBasedEventHandler::BeginEvent(CellBasedEventHandler::POSITION); UpdateNodePositions(); CellBasedEventHandler::EndEvent(CellBasedEventHandler::POSITION); }
MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::MeshBasedCellPopulation(MutableMesh<ELEMENT_DIM,SPACE_DIM>& rMesh, std::vector<CellPtr>& rCells, const std::vector<unsigned> locationIndices, bool deleteMesh, bool validate) : AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>(rMesh, rCells, locationIndices), mpVoronoiTessellation(NULL), mDeleteMesh(deleteMesh), mUseAreaBasedDampingConstant(false), mAreaBasedDampingConstantParameter(0.1), mWriteVtkAsPoints(false), mOutputMeshInVtk(false), mHasVariableRestLength(false) { mpMutableMesh = static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>* >(&(this->mrMesh)); assert(this->mCells.size() <= this->mrMesh.GetNumNodes()); if (validate) { Validate(); } // Initialise the applied force at each node to zero for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->rGetMesh().GetNodeIteratorBegin(); node_iter != this->rGetMesh().GetNodeIteratorEnd(); ++node_iter) { node_iter->ClearAppliedForce(); } }
void OffLatticeSimulation<ELEMENT_DIM,SPACE_DIM>::SetupSolve() { // Clear all forces for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->mrCellPopulation.rGetMesh().GetNodeIteratorBegin(); node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd(); ++node_iter) { node_iter->ClearAppliedForce(); } }
void MeshBasedCellPopulationWithGhostNodes<DIM>::ApplyGhostForces(){ // Initialise vector of forces on ghost nodes std::vector<c_vector<double, DIM> > drdt(this->GetNumNodes()); for (unsigned i=0; i<drdt.size(); i++) { drdt[i] = zero_vector<double>(DIM); } // Calculate forces on ghost nodes for (typename MutableMesh<DIM, DIM>::EdgeIterator edge_iterator = static_cast<MutableMesh<DIM, DIM>&>((this->mrMesh)).EdgesBegin(); edge_iterator != static_cast<MutableMesh<DIM, DIM>&>((this->mrMesh)).EdgesEnd(); ++edge_iterator) { unsigned nodeA_global_index = edge_iterator.GetNodeA()->GetIndex(); unsigned nodeB_global_index = edge_iterator.GetNodeB()->GetIndex(); c_vector<double, DIM> force = CalculateForceBetweenGhostNodes(nodeA_global_index, nodeB_global_index); if (!this->mIsGhostNode[nodeA_global_index]) { drdt[nodeB_global_index] -= force; } else { drdt[nodeA_global_index] += force; if (this->mIsGhostNode[nodeB_global_index]) { drdt[nodeB_global_index] -= force; } } } 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->mIsGhostNode[node_index]) { node_iter->ClearAppliedForce(); node_iter->AddAppliedForceContribution(drdt[node_index]); } } };
void OffLatticeSimulation<ELEMENT_DIM,SPACE_DIM>::SetupSolve() { // Clear all forces for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->mrCellPopulation.rGetMesh().GetNodeIteratorBegin(); node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd(); ++node_iter) { node_iter->ClearAppliedForce(); } // Use a forward Euler method by default, unless a numerical method has been specified already if (mpNumericalMethod == nullptr) { mpNumericalMethod = boost::make_shared<ForwardEulerNumericalMethod<ELEMENT_DIM, SPACE_DIM> >(); } mpNumericalMethod->SetCellPopulation(dynamic_cast<AbstractOffLatticeCellPopulation<ELEMENT_DIM,SPACE_DIM>*>(&(this->mrCellPopulation))); mpNumericalMethod->SetForceCollection(&mForceCollection); }