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 #include "WelikyOsterForce.hpp"
00029
00030 template<unsigned DIM>
00031 WelikyOsterForce<DIM>::WelikyOsterForce()
00032 : AbstractForce<DIM>(),
00033 mWelikyOsterAreaParameter(1.0),
00034 mWelikyOsterPerimeterParameter(1.0)
00035 {
00036 }
00037
00038 template<unsigned DIM>
00039 WelikyOsterForce<DIM>::~WelikyOsterForce()
00040 {
00041 }
00042
00043 template<unsigned DIM>
00044 void WelikyOsterForce<DIM>::AddForceContribution(std::vector<c_vector<double, DIM> >& rForces,
00045 AbstractCellPopulation<DIM>& rCellPopulation)
00046 {
00047
00048 assert(DIM == 2);
00049
00050
00051 if (dynamic_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation) == NULL)
00052 {
00053 EXCEPTION("WelikyOsterForce is to be used with a VertexBasedCellPopulation only");
00054 }
00055
00056
00057 VertexBasedCellPopulation<DIM>* p_cell_population = static_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation);
00058
00059
00060
00061
00062
00063
00064
00065 for (typename VertexMesh<DIM,DIM>::VertexElementIterator element_iter = p_cell_population->rGetMesh().GetElementIteratorBegin();
00066 element_iter != p_cell_population->rGetMesh().GetElementIteratorEnd();
00067 ++element_iter)
00068 {
00069 unsigned element_index = element_iter->GetIndex();
00070
00071
00072
00073
00074 double element_area = p_cell_population->rGetMesh().GetVolumeOfElement(element_index);
00075
00076 double deformation_coefficient = GetWelikyOsterAreaParameter()/element_area;
00077
00078
00079
00080
00081
00082
00083 double element_perimeter = p_cell_population->rGetMesh().GetSurfaceAreaOfElement(element_index);
00084
00085 double membrane_surface_tension_coefficient = GetWelikyOsterPerimeterParameter()*element_perimeter;
00086
00087
00088
00089 unsigned num_nodes = element_iter->GetNumNodes();
00090 for (unsigned node_local_index = 0; node_local_index < num_nodes; node_local_index++)
00091 {
00092 unsigned node_global_index = element_iter->GetNodeGlobalIndex(node_local_index);
00093
00094 c_vector<double, DIM> current_node = element_iter->GetNodeLocation(node_local_index);
00095 c_vector<double, DIM> next_node = element_iter->GetNodeLocation((node_local_index + 1)%(element_iter->GetNumNodes()));
00096 c_vector<double, DIM> previous_node = element_iter->GetNodeLocation((node_local_index + element_iter->GetNumNodes() - 1)%(element_iter->GetNumNodes()));
00097
00098 c_vector<double, DIM> clockwise_unit_vector = p_cell_population->rGetMesh().GetVectorFromAtoB(current_node, previous_node);
00099 clockwise_unit_vector /= norm_2(clockwise_unit_vector);
00100 c_vector<double, DIM> anti_clockwise_unit_vector = p_cell_population->rGetMesh().GetVectorFromAtoB(current_node, next_node);
00101 anti_clockwise_unit_vector /= norm_2(anti_clockwise_unit_vector);
00102
00103
00104 c_vector<double, DIM> outward_normal = -0.5*clockwise_unit_vector - 0.5*anti_clockwise_unit_vector;
00105 outward_normal /= norm_2(outward_normal);
00106
00107 c_vector<double, DIM> deformation_contribution = deformation_coefficient * outward_normal;
00108
00109 c_vector<double, DIM> membrane_surface_tension_contribution = membrane_surface_tension_coefficient * (clockwise_unit_vector + anti_clockwise_unit_vector);
00110
00111 c_vector<double, DIM> force_on_node = deformation_contribution +
00112 membrane_surface_tension_contribution;
00113
00114 rForces[node_global_index] += force_on_node;
00115 }
00116 }
00117 }
00118
00119 template<unsigned DIM>
00120 double WelikyOsterForce<DIM>::GetWelikyOsterAreaParameter()
00121 {
00122 return mWelikyOsterAreaParameter;
00123 }
00124
00125 template<unsigned DIM>
00126 double WelikyOsterForce<DIM>::GetWelikyOsterPerimeterParameter()
00127 {
00128 return mWelikyOsterPerimeterParameter;
00129 }
00130
00131 template<unsigned DIM>
00132 void WelikyOsterForce<DIM>::SetWelikyOsterAreaParameter(double welikyOsterAreaParameter)
00133 {
00134 mWelikyOsterAreaParameter = welikyOsterAreaParameter;
00135 }
00136
00137 template<unsigned DIM>
00138 void WelikyOsterForce<DIM>::SetWelikyOsterPerimeterParameter(double welikyOsterPerimeterParameter)
00139 {
00140 mWelikyOsterPerimeterParameter = welikyOsterPerimeterParameter;
00141 }
00142
00143 template<unsigned DIM>
00144 void WelikyOsterForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00145 {
00146 *rParamsFile << "\t\t\t<WelikyOsterAreaParameter>" << mWelikyOsterAreaParameter << "</WelikyOsterAreaParameter> \n";
00147 *rParamsFile << "\t\t\t<WelikyOsterPerimeterParameter>" << mWelikyOsterPerimeterParameter << "</WelikyOsterPerimeterParameter> \n";
00148
00149
00150 AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00151 }
00152
00154
00156
00157 template class WelikyOsterForce<1>;
00158 template class WelikyOsterForce<2>;
00159 template class WelikyOsterForce<3>;
00160
00161
00162
00163 #include "SerializationExportWrapperForCpp.hpp"
00164 EXPORT_TEMPLATE_CLASS_SAME_DIMS(WelikyOsterForce)