AbstractTwoBodyInteractionForce.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 #include "AbstractTwoBodyInteractionForce.hpp"
00030 
00031 template<unsigned DIM>
00032 AbstractTwoBodyInteractionForce<DIM>::AbstractTwoBodyInteractionForce()
00033    : AbstractForce<DIM>(),
00034      mUseCutOffLength(false),
00035      mMechanicsCutOffLength(DBL_MAX)
00036 {
00037 }
00038 
00039 template<unsigned DIM>
00040 bool AbstractTwoBodyInteractionForce<DIM>::GetUseCutOffLength()
00041 {
00042     return mUseCutOffLength;
00043 }
00044 
00045 template<unsigned DIM>
00046 void AbstractTwoBodyInteractionForce<DIM>::SetCutOffLength(double cutOffLength)
00047 {
00048     assert(cutOffLength > 0.0);
00049     mUseCutOffLength = true;
00050     mMechanicsCutOffLength = cutOffLength;
00051 }
00052 
00053 template<unsigned DIM>
00054 double AbstractTwoBodyInteractionForce<DIM>::GetCutOffLength()
00055 {
00056     return mMechanicsCutOffLength;
00057 }
00058 
00059 template<unsigned DIM>
00060 void AbstractTwoBodyInteractionForce<DIM>::AddForceContribution(std::vector<c_vector<double, DIM> >& rForces,
00061                                                                 AbstractCellPopulation<DIM>& rCellPopulation)
00062 {
00063     // Throw an exception message if not using a subclass of AbstractCentreBasedCellPopulation
00064     if (dynamic_cast<AbstractCentreBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL)
00065     {
00066         EXCEPTION("Subclasses of AbstractTwoBodyInteractionForce are to be used with subclasses of AbstractCentreBasedCellPopulation only");
00067     }
00068 
00069     if (dynamic_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation))
00070     {
00071         MeshBasedCellPopulation<DIM>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation);
00072 
00073         // Iterate over all springs and add force contributions
00074         for (typename MeshBasedCellPopulation<DIM>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin();
00075              spring_iterator != p_static_cast_cell_population->SpringsEnd();
00076              ++spring_iterator)
00077         {
00078             unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex();
00079             unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex();
00080 
00081             // Calculate the force between nodes
00082             c_vector<double, DIM> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation);
00083 
00084             // Add the force contribution to each node
00085             rForces[nodeB_global_index] -= force;
00086             rForces[nodeA_global_index] += force;
00087         }
00088     }
00089     else
00090     {
00091         std::set< std::pair<Node<DIM>*, Node<DIM>* > >& r_node_pairs = (static_cast<NodeBasedCellPopulation<DIM>*>(&rCellPopulation))->rGetNodePairs();
00092 
00093 //        assert(DIM==2); // 3d boxes not implemented yet - if fails nightly uncomment the double node loop below
00094                         // and use that for the 3d case
00095         for (typename std::set< std::pair<Node<DIM>*, Node<DIM>* > >::iterator iter = r_node_pairs.begin();
00096             iter != r_node_pairs.end();
00097             iter++)
00098         {
00099             std::pair<Node<DIM>*, Node<DIM>* > pair = *iter;
00100 
00101             unsigned node_a_index = pair.first->GetIndex();
00102             unsigned node_b_index = pair.second->GetIndex();
00103 
00104             // Calculate the force between nodes
00105             c_vector<double, DIM> force = CalculateForceBetweenNodes(node_a_index, node_b_index, rCellPopulation);
00106             for (unsigned j=0; j<DIM; j++)
00107             {
00108                 assert(!std::isnan(force[j]));
00109             }
00110 
00111             // Add the force contribution to each node
00112             rForces[node_a_index] += force;
00113             rForces[node_b_index] -= force;
00114         }
00115 
00116 //        // Iterate over nodes
00117 //        for (unsigned node_a_index=0; node_a_index<rCellPopulation.GetNumNodes(); node_a_index++)
00118 //        {
00119 //            // Iterate over nodes
00120 //            for (unsigned node_b_index=node_a_index+1; node_b_index<rCellPopulation.GetNumNodes(); node_b_index++)
00121 //            {
00122 //                // Calculate the force between nodes
00123 //                c_vector<double, DIM> force = CalculateForceBetweenNodes(node_a_index, node_b_index, rCellPopulation);
00124 //                for (unsigned j=0; j<DIM; j++)
00125 //                {
00126 //                    assert(!std::isnan(force[j]));
00127 //                }
00128 //
00129 //                // Add the force contribution to each node
00130 //                rForces[node_a_index] += force;
00131 //                rForces[node_b_index] -= force;
00132 //            }
00133 //        }
00134     }
00135 }
00136 
00137 template<unsigned DIM>
00138 void AbstractTwoBodyInteractionForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00139 {
00140     *rParamsFile << "\t\t\t<UseCutOffLength>" << mUseCutOffLength << "</UseCutOffLength>\n";
00141     *rParamsFile << "\t\t\t<CutOffLength>" << mMechanicsCutOffLength << "</CutOffLength>\n";
00142 
00143     // Call method on direct parent class
00144     AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00145 }
00146 
00148 // Explicit instantiation
00150 
00151 template class AbstractTwoBodyInteractionForce<1>;
00152 template class AbstractTwoBodyInteractionForce<2>;
00153 template class AbstractTwoBodyInteractionForce<3>;
Generated on Thu Dec 22 13:00:05 2011 for Chaste by  doxygen 1.6.3