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 VertexBasedCellPopulation<DIM>* p_cell_population = static_cast<VertexBasedCellPopulation<DIM>*>(&rCellPopulation);
00052
00053
00054
00055
00056
00057
00058
00059 for (typename VertexMesh<DIM,DIM>::VertexElementIterator element_iter = p_cell_population->rGetMesh().GetElementIteratorBegin();
00060 element_iter != p_cell_population->rGetMesh().GetElementIteratorEnd();
00061 ++element_iter)
00062 {
00063 unsigned element_index = element_iter->GetIndex();
00064
00065
00066
00067
00068 double element_area = p_cell_population->rGetMesh().GetVolumeOfElement(element_index);
00069
00070 double deformation_coefficient = GetWelikyOsterAreaParameter()/element_area;
00071
00072
00073
00074
00075
00076
00077 double element_perimeter = p_cell_population->rGetMesh().GetSurfaceAreaOfElement(element_index);
00078
00079 double membrane_surface_tension_coefficient = GetWelikyOsterPerimeterParameter()*element_perimeter;
00080
00081
00082
00083 unsigned num_nodes = element_iter->GetNumNodes();
00084 for (unsigned node_local_index = 0; node_local_index < num_nodes; node_local_index++)
00085 {
00086 unsigned node_global_index = element_iter->GetNodeGlobalIndex(node_local_index);
00087
00088 c_vector<double, DIM> current_node = element_iter->GetNodeLocation(node_local_index);
00089 c_vector<double, DIM> next_node = element_iter->GetNodeLocation((node_local_index + 1)%(element_iter->GetNumNodes()));
00090 c_vector<double, DIM> previous_node = element_iter->GetNodeLocation((node_local_index + element_iter->GetNumNodes() - 1)%(element_iter->GetNumNodes()));
00091
00092 c_vector<double, DIM> clockwise_unit_vector = p_cell_population->rGetMesh().GetVectorFromAtoB(current_node, previous_node);
00093 clockwise_unit_vector /= norm_2(clockwise_unit_vector);
00094 c_vector<double, DIM> anti_clockwise_unit_vector = p_cell_population->rGetMesh().GetVectorFromAtoB(current_node, next_node);
00095 anti_clockwise_unit_vector /= norm_2(anti_clockwise_unit_vector);
00096
00097
00098 c_vector<double, DIM> outward_normal = -0.5*clockwise_unit_vector - 0.5*anti_clockwise_unit_vector;
00099 outward_normal /= norm_2(outward_normal);
00100
00101 c_vector<double, DIM> deformation_contribution = deformation_coefficient * outward_normal;
00102
00103 c_vector<double, DIM> membrane_surface_tension_contribution = membrane_surface_tension_coefficient * (clockwise_unit_vector + anti_clockwise_unit_vector);
00104
00105 c_vector<double, DIM> force_on_node = deformation_contribution +
00106 membrane_surface_tension_contribution;
00107
00108 rForces[node_global_index] += force_on_node;
00109 }
00110 }
00111 }
00112
00113 template<unsigned DIM>
00114 double WelikyOsterForce<DIM>::GetWelikyOsterAreaParameter()
00115 {
00116 return mWelikyOsterAreaParameter;
00117 }
00118
00119 template<unsigned DIM>
00120 double WelikyOsterForce<DIM>::GetWelikyOsterPerimeterParameter()
00121 {
00122 return mWelikyOsterPerimeterParameter;
00123 }
00124
00125 template<unsigned DIM>
00126 void WelikyOsterForce<DIM>::SetWelikyOsterAreaParameter(double welikyOsterAreaParameter)
00127 {
00128 mWelikyOsterAreaParameter = welikyOsterAreaParameter;
00129 }
00130
00131 template<unsigned DIM>
00132 void WelikyOsterForce<DIM>::SetWelikyOsterPerimeterParameter(double welikyOsterPerimeterParameter)
00133 {
00134 mWelikyOsterPerimeterParameter = welikyOsterPerimeterParameter;
00135 }
00136
00137 template<unsigned DIM>
00138 void WelikyOsterForce<DIM>::OutputForceParameters(out_stream& rParamsFile)
00139 {
00140 *rParamsFile << "\t\t\t<WelikyOsterAreaParameter>"<< mWelikyOsterAreaParameter << "</WelikyOsterAreaParameter> \n" ;
00141 *rParamsFile << "\t\t\t<WelikyOsterPerimeterParameter>"<< mWelikyOsterPerimeterParameter << "</WelikyOsterPerimeterParameter> \n" ;
00142
00143
00144 AbstractForce<DIM>::OutputForceParameters(rParamsFile);
00145 }
00146
00148
00150
00151 template class WelikyOsterForce<1>;
00152 template class WelikyOsterForce<2>;
00153 template class WelikyOsterForce<3>;
00154
00155
00156
00157 #include "SerializationExportWrapperForCpp.hpp"
00158 EXPORT_TEMPLATE_CLASS_SAME_DIMS(WelikyOsterForce)