PlaneBoundaryCondition.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 "PlaneBoundaryCondition.hpp"
00030 #include "AbstractCentreBasedCellPopulation.hpp"
00031 #include "VertexBasedCellPopulation.hpp"
00032 #include "Debug.hpp"
00033
00034 template<unsigned DIM>
00035 PlaneBoundaryCondition<DIM>::PlaneBoundaryCondition(AbstractCellPopulation<DIM>* pCellPopulation,
00036 c_vector<double, DIM> point,
00037 c_vector<double, DIM> normal)
00038 : AbstractCellPopulationBoundaryCondition<DIM>(pCellPopulation),
00039 mPointOnPlane(point)
00040 {
00041 assert(norm_2(normal) > 0.0);
00042 mNormalToPlane = normal/norm_2(normal);
00043 }
00044
00045 template<unsigned DIM>
00046 const c_vector<double, DIM>& PlaneBoundaryCondition<DIM>::rGetPointOnPlane() const
00047 {
00048 return mPointOnPlane;
00049 }
00050
00051 template<unsigned DIM>
00052 const c_vector<double, DIM>& PlaneBoundaryCondition<DIM>::rGetNormalToPlane() const
00053 {
00054 return mNormalToPlane;
00055 }
00056
00057 template<unsigned DIM>
00058 void PlaneBoundaryCondition<DIM>::ImposeBoundaryCondition(const std::vector< c_vector<double, DIM> >& rOldLocations)
00059 {
00060
00061 if (dynamic_cast<AbstractOffLatticeCellPopulation<DIM>*>(this->mpCellPopulation)==NULL)
00062 {
00063 EXCEPTION("PlaneBoundaryCondition requires a subclass of AbstractOffLatticeCellPopulation.");
00064 }
00065
00066 assert((dynamic_cast<AbstractCentreBasedCellPopulation<DIM>*>(this->mpCellPopulation))
00067 || (dynamic_cast<VertexBasedCellPopulation<DIM>*>(this->mpCellPopulation)) );
00068
00069 if (DIM==2)
00070 {
00071 if(dynamic_cast<AbstractCentreBasedCellPopulation<DIM>*>(this->mpCellPopulation))
00072 {
00073 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->mpCellPopulation->Begin();
00074 cell_iter != this->mpCellPopulation->End();
00075 ++cell_iter)
00076 {
00077 c_vector<double, DIM> cell_location = this->mpCellPopulation->GetLocationOfCellCentre(*cell_iter);
00078
00079 unsigned node_index = this->mpCellPopulation->GetLocationIndexUsingCell(*cell_iter);
00080 Node<DIM>* p_node = this->mpCellPopulation->GetNode(node_index);
00081
00082 if (inner_prod(cell_location - mPointOnPlane,mNormalToPlane) > 0.0)
00083 {
00084 c_vector<double, 2> tangent;
00085 tangent(0) = -mNormalToPlane(1);
00086 tangent(1) = mNormalToPlane(0);
00087
00088 c_vector<double, 2> intersection = mPointOnPlane + inner_prod(tangent,cell_location- mPointOnPlane)*tangent;
00089
00090 p_node->rGetModifiableLocation() = intersection;
00091 }
00092 }
00093 }
00094 else
00095 {
00096 assert(dynamic_cast<VertexBasedCellPopulation<DIM>*>(this->mpCellPopulation));
00097
00098 VertexBasedCellPopulation<DIM>* pStaticCastCellPopulation = static_cast<VertexBasedCellPopulation<DIM>*>(this->mpCellPopulation);
00099
00100
00101 unsigned num_nodes = pStaticCastCellPopulation->GetNumNodes();
00102 for (unsigned node_index=0; node_index<num_nodes; node_index++)
00103 {
00104 Node<DIM>* p_node = pStaticCastCellPopulation->GetNode(node_index);
00105 c_vector<double, DIM> node_location = p_node->rGetLocation();
00106
00107 if (inner_prod(node_location - mPointOnPlane,mNormalToPlane) > 0.0)
00108 {
00109 c_vector<double, 2> tangent;
00110 tangent(0) = -mNormalToPlane(1);
00111 tangent(1) = mNormalToPlane(0);
00112
00113 c_vector<double, 2> intersection = mPointOnPlane + inner_prod(tangent,node_location- mPointOnPlane)*tangent;
00114
00115 p_node->rGetModifiableLocation() = intersection;
00116 }
00117 }
00118 }
00119
00120 }
00121 else
00122 {
00123 EXCEPTION("PlaneBoundaryCondition is not yet implemented in 1D or 3D");
00124 }
00125 }
00126
00127 template<unsigned DIM>
00128 bool PlaneBoundaryCondition<DIM>::VerifyBoundaryCondition()
00129 {
00130 bool condition_satisfied = true;
00131
00132 if (DIM==2)
00133 {
00134 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->mpCellPopulation->Begin();
00135 cell_iter != this->mpCellPopulation->End();
00136 ++cell_iter)
00137 {
00138 c_vector<double, DIM> cell_location = this->mpCellPopulation->GetLocationOfCellCentre(*cell_iter);
00139
00140 if (inner_prod(cell_location - mPointOnPlane,mNormalToPlane) > 0.0)
00141 {
00142 condition_satisfied = false;
00143 break;
00144 }
00145 }
00146 }
00147 else
00148 {
00149 EXCEPTION("PlaneBoundaryCondition is not yet implemented in 1D or 3D");
00150 }
00151
00152 return condition_satisfied;
00153 }
00154
00155 template<unsigned DIM>
00156 void PlaneBoundaryCondition<DIM>::OutputCellPopulationBoundaryConditionParameters(out_stream& rParamsFile)
00157 {
00158 *rParamsFile << "\t\t\t<PointOnPlane>";
00159 for (unsigned index=0; index != DIM-1U; index++)
00160 {
00161 *rParamsFile << mPointOnPlane[index] << ",";
00162 }
00163 *rParamsFile << mPointOnPlane[DIM-1] << "</PointOnPlane>\n";
00164
00165 *rParamsFile << "\t\t\t<NormalToPlane>";
00166 for (unsigned index=0; index != DIM-1U; index++)
00167 {
00168 *rParamsFile << mNormalToPlane[index] << ",";
00169 }
00170 *rParamsFile << mNormalToPlane[DIM-1] << "</NormalToPlane>\n";
00171
00172
00173 AbstractCellPopulationBoundaryCondition<DIM>::OutputCellPopulationBoundaryConditionParameters(rParamsFile);
00174 }
00175
00177
00179
00180 template class PlaneBoundaryCondition<1>;
00181 template class PlaneBoundaryCondition<2>;
00182 template class PlaneBoundaryCondition<3>;
00183
00184
00185 #include "SerializationExportWrapperForCpp.hpp"
00186 EXPORT_TEMPLATE_CLASS_SAME_DIMS(PlaneBoundaryCondition)