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