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