void AbstractTwoBodyInteractionForce<ELEMENT_DIM,SPACE_DIM>::AddForceContribution(AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>& rCellPopulation) { // Throw an exception message if not using a subclass of AbstractCentreBasedCellPopulation if (dynamic_cast<AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>*>(&rCellPopulation) == nullptr) { EXCEPTION("Subclasses of AbstractTwoBodyInteractionForce are to be used with subclasses of AbstractCentreBasedCellPopulation only"); } ///\todo this could be tidied by using the rGetNodePairs for all populations and moving the below calculation into the MutableMesh. if (bool(dynamic_cast<MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>*>(&rCellPopulation))) { MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>*>(&rCellPopulation); // Iterate over all springs and add force contributions for (typename MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin(); spring_iterator != p_static_cast_cell_population->SpringsEnd(); ++spring_iterator) { unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex(); unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex(); // Calculate the force between nodes c_vector<double, SPACE_DIM> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation); // Add the force contribution to each node c_vector<double, SPACE_DIM> negative_force = -1.0*force; spring_iterator.GetNodeB()->AddAppliedForceContribution(negative_force); spring_iterator.GetNodeA()->AddAppliedForceContribution(force); } } else // This is a NodeBasedCellPopulation { AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>* p_static_cast_cell_population = static_cast<AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>*>(&rCellPopulation); std::vector< std::pair<Node<SPACE_DIM>*, Node<SPACE_DIM>* > >& r_node_pairs = p_static_cast_cell_population->rGetNodePairs(); for (typename std::vector< std::pair<Node<SPACE_DIM>*, Node<SPACE_DIM>* > >::iterator iter = r_node_pairs.begin(); iter != r_node_pairs.end(); iter++) { std::pair<Node<SPACE_DIM>*, Node<SPACE_DIM>* > pair = *iter; unsigned node_a_index = pair.first->GetIndex(); unsigned node_b_index = pair.second->GetIndex(); // Calculate the force between nodes c_vector<double, SPACE_DIM> force = CalculateForceBetweenNodes(node_a_index, node_b_index, rCellPopulation); for (unsigned j=0; j<SPACE_DIM; j++) { assert(!std::isnan(force[j])); } // Add the force contribution to each node c_vector<double, SPACE_DIM> negative_force = -1.0*force; pair.first->AddAppliedForceContribution(force); pair.second->AddAppliedForceContribution(negative_force); } } }
void CryptProjectionForce::AddForceContribution(AbstractCellPopulation<2>& rCellPopulation) { // First work out the 3D location of each cell UpdateNode3dLocationMap(rCellPopulation); // Throw an exception message if not using a MeshBasedCellPopulation if (dynamic_cast<MeshBasedCellPopulation<2>*>(&rCellPopulation) == NULL) { EXCEPTION("CryptProjectionForce is to be used with a subclass of MeshBasedCellPopulation only"); } MeshBasedCellPopulation<2>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<2>*>(&rCellPopulation); for (MeshBasedCellPopulation<2>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin(); spring_iterator != p_static_cast_cell_population->SpringsEnd(); ++spring_iterator) { unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex(); unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex(); c_vector<double, 2> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation); c_vector<double, 2> negative_force = -1.0 * force; spring_iterator.GetNodeB()->AddAppliedForceContribution(negative_force); spring_iterator.GetNodeA()->AddAppliedForceContribution(force); } if (mIncludeWntChemotaxis) { assert(WntConcentration<2>::Instance()->IsWntSetUp()); for (AbstractCellPopulation<2>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { if (cell_iter->GetCellProliferativeType()->IsType<StemCellProliferativeType>()) { c_vector<double, 2> wnt_chemotactic_force = mWntChemotaxisStrength*WntConcentration<2>::Instance()->GetWntGradient(*cell_iter); unsigned index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter); rCellPopulation.GetNode(index)->AddAppliedForceContribution(wnt_chemotactic_force); } } } }