00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "AbstractTwoBodyInteractionForce.hpp"
00030
00031
00032 template<unsigned DIM>
00033 AbstractTwoBodyInteractionForce<DIM>::AbstractTwoBodyInteractionForce()
00034 : AbstractForce<DIM>(),
00035 mUseCutOffLength(false),
00036 mMechanicsCutOffLength(DBL_MAX)
00037 {
00038 }
00039
00040 template<unsigned DIM>
00041 bool AbstractTwoBodyInteractionForce<DIM>::GetUseCutOffLength()
00042 {
00043 return mUseCutOffLength;
00044 }
00045
00046 template<unsigned DIM>
00047 void AbstractTwoBodyInteractionForce<DIM>::SetCutOffLength(double cutOffLength)
00048 {
00049 assert(cutOffLength > 0.0);
00050 mUseCutOffLength = true;
00051 mMechanicsCutOffLength = cutOffLength;
00052 }
00053
00054
00055 template<unsigned DIM>
00056 double AbstractTwoBodyInteractionForce<DIM>::GetCutOffLength()
00057 {
00058 return mMechanicsCutOffLength;
00059 }
00060
00061
00062 template<unsigned DIM>
00063 void AbstractTwoBodyInteractionForce<DIM>::AddForceContribution(std::vector<c_vector<double, DIM> >& rForces,
00064 AbstractCellPopulation<DIM>& rCellPopulation)
00065 {
00066
00067 if (dynamic_cast<AbstractCentreBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL)
00068 {
00069 EXCEPTION("Subclasses of AbstractTwoBodyInteractionForce are to be used with subclasses of AbstractCentreBasedCellPopulation only");
00070 }
00071
00072 if (rCellPopulation.IsMeshBasedCellPopulation())
00073 {
00074 MeshBasedCellPopulation<DIM>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation);
00075
00076
00077 for (typename MeshBasedCellPopulation<DIM>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin();
00078 spring_iterator != p_static_cast_cell_population->SpringsEnd();
00079 ++spring_iterator)
00080 {
00081 unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex();
00082 unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex();
00083
00084
00085 c_vector<double, DIM> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation);
00086
00087
00088 rForces[nodeB_global_index] -= force;
00089 rForces[nodeA_global_index] += force;
00090 }
00091 }
00092 else
00093 {
00094 std::set< std::pair<Node<DIM>*, Node<DIM>* > >& r_node_pairs = (static_cast<NodeBasedCellPopulation<DIM>*>(&rCellPopulation))->rGetNodePairs();
00095
00096
00097
00098 for (typename std::set< std::pair<Node<DIM>*, Node<DIM>* > >::iterator iter = r_node_pairs.begin();
00099 iter != r_node_pairs.end();
00100 iter++)
00101 {
00102 std::pair<Node<DIM>*, Node<DIM>* > pair = *iter;
00103
00104 unsigned node_a_index = pair.first->GetIndex();
00105 unsigned node_b_index = pair.second->GetIndex();
00106
00107
00108 c_vector<double, DIM> force = CalculateForceBetweenNodes(node_a_index, node_b_index, rCellPopulation);
00109 for (unsigned j=0; j<DIM; j++)
00110 {
00111 assert(!std::isnan(force[j]));
00112 }
00113
00114
00115 rForces[node_a_index] += force;
00116 rForces[node_b_index] -= force;
00117 }
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 }
00138 }
00139
00140 template<unsigned DIM>
00141 void AbstractTwoBodyInteractionForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00142 {
00143 *rParamsFile << "\t\t\t<UseCutOffLength>" << mUseCutOffLength << "</UseCutOffLength> \n";
00144 *rParamsFile << "\t\t\t<CutOffLength>" << mMechanicsCutOffLength << "</CutOffLength> \n";
00145
00146
00147 AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00148 }
00149
00151
00153
00154 template class AbstractTwoBodyInteractionForce<1>;
00155 template class AbstractTwoBodyInteractionForce<2>;
00156 template class AbstractTwoBodyInteractionForce<3>;