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);
        }
    }
}
Пример #2
0
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);
            }
        }
    }
}