NodeBasedCellPopulationWithBuskeUpdate.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 #include "NodeBasedCellPopulationWithBuskeUpdate.hpp"
00036
00037 #include "ReplicatableVector.hpp"
00038 #include "OdeLinearSystemSolver.hpp"
00039
00040 template<unsigned DIM>
00041 NodeBasedCellPopulationWithBuskeUpdate<DIM>::NodeBasedCellPopulationWithBuskeUpdate(NodesOnlyMesh<DIM>& rMesh,
00042 std::vector<CellPtr>& rCells,
00043 const std::vector<unsigned> locationIndices,
00044 bool deleteMesh)
00045 : NodeBasedCellPopulation<DIM>(rMesh, rCells, locationIndices, deleteMesh)
00046 {
00047 }
00048
00049 template<unsigned DIM>
00050 NodeBasedCellPopulationWithBuskeUpdate<DIM>::NodeBasedCellPopulationWithBuskeUpdate(NodesOnlyMesh<DIM>& rMesh)
00051 : NodeBasedCellPopulation<DIM>(rMesh)
00052 {
00053
00054 }
00055
00056 template<unsigned DIM>
00057 void NodeBasedCellPopulationWithBuskeUpdate<DIM>::UpdateNodeLocations(double dt)
00058 {
00059
00060 unsigned system_size = this->GetNumNodes()*DIM;
00061
00062 OdeLinearSystemSolver solver(system_size, dt);
00063
00064
00065 Mat& r_matrix = solver.rGetLhsMatrix();
00066
00067
00068 Vec initial_condition = PetscTools::CreateAndSetVec(system_size, 0.0);
00069
00070
00071 Vec& r_vector = solver.rGetForceVector();
00072
00073
00074 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00075 cell_iter != this->End();
00076 ++cell_iter)
00077 {
00078
00079 unsigned global_node_index = this->GetLocationIndexUsingCell((*cell_iter));
00080
00081
00082 unsigned node_index = this->rGetMesh().SolveNodeMapping(global_node_index);
00083
00084 Node<DIM>* p_node_i = this->GetNode(global_node_index);
00085
00086
00087 c_vector<double, DIM> node_i_location = p_node_i->rGetLocation();
00088
00089
00090 double radius_of_cell_i = p_node_i->GetRadius();
00091
00092
00093 double damping_const = this->GetDampingConstant(global_node_index);
00094
00095
00096
00097
00098 std::set<unsigned> neighbouring_node_indices = this->GetNeighbouringNodeIndices(global_node_index);
00099
00100 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
00101 iter != neighbouring_node_indices.end();
00102 ++iter)
00103 {
00104 unsigned neighbour_node_global_index = *iter;
00105
00106 unsigned neighbour_node_index = this->rGetMesh().SolveNodeMapping(neighbour_node_global_index);
00107
00108
00109 double Aij = 0.0;
00110
00111 Node<DIM>* p_node_j = this->GetNode(neighbour_node_global_index);
00112
00113
00114 c_vector<double, DIM> node_j_location = p_node_j->rGetLocation();
00115
00116
00117 c_vector<double, DIM> unit_vector = node_j_location - node_i_location;
00118
00119
00120 double dij = norm_2(unit_vector);
00121
00122 unit_vector /= dij;
00123
00124
00125 double radius_of_cell_j = p_node_j->GetRadius();
00126
00127 if (dij < radius_of_cell_i + radius_of_cell_j)
00128 {
00129
00130 double xij = 0.5*(radius_of_cell_i*radius_of_cell_i - radius_of_cell_j*radius_of_cell_j + dij*dij)/dij;
00131
00132 Aij = M_PI*(radius_of_cell_i*radius_of_cell_i - xij*xij);
00133
00134
00135 for (unsigned i=0; i<DIM; i++)
00136 {
00137 PetscMatTools::AddToElement(r_matrix, DIM*neighbour_node_index+i, DIM*neighbour_node_index+i, -damping_const*Aij);
00138 PetscMatTools::AddToElement(r_matrix, DIM*node_index+i, DIM*node_index+i, damping_const*Aij);
00139 }
00140 }
00141 }
00142
00143
00144 for (unsigned i=0; i<DIM; i++)
00145 {
00146 PetscMatTools::AddToElement(r_matrix, DIM*node_index+i, DIM*node_index+i, damping_const);
00147 }
00148
00149
00150
00151
00152 c_vector<double, DIM> current_location;
00153 c_vector<double, DIM> forces;
00154 current_location = this->GetNode(global_node_index)->rGetLocation();
00155 forces = this->GetNode(global_node_index)->rGetAppliedForce();
00156
00157 for (unsigned i=0; i<DIM; i++)
00158 {
00159 PetscVecTools::SetElement(initial_condition, DIM*node_index+i, current_location(i));
00160 PetscVecTools::SetElement(r_vector, DIM*node_index+i, forces(i));
00161 }
00162 }
00163 PetscMatTools::Finalise(r_matrix);
00164
00165 solver.SetInitialConditionVector(initial_condition);
00166
00167
00168 Vec soln_next_timestep = solver.SolveOneTimeStep();
00169
00170 ReplicatableVector soln_next_timestep_repl(soln_next_timestep);
00171
00172
00173 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00174 cell_iter != this->End();
00175 ++cell_iter)
00176 {
00177
00178 unsigned global_node_index = this->GetLocationIndexUsingCell((*cell_iter));
00179
00180 unsigned node_index = this->rGetMesh().SolveNodeMapping(global_node_index);
00181
00182 c_vector<double, DIM> new_node_location;
00183
00184
00185 for (unsigned i=0; i<DIM; i++)
00186 {
00187 new_node_location(i) = soln_next_timestep_repl[DIM*node_index+i];
00188 }
00189
00190
00191 ChastePoint<DIM> new_point(new_node_location);
00192
00193
00194 this->SetNode(global_node_index, new_point);
00195 }
00196
00197
00198 PetscTools::Destroy(initial_condition);
00199 }
00200
00201 template<unsigned DIM>
00202 void NodeBasedCellPopulationWithBuskeUpdate<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00203 {
00204
00205
00206
00207 NodeBasedCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
00208 }
00209
00211
00213
00214 template class NodeBasedCellPopulationWithBuskeUpdate<1>;
00215 template class NodeBasedCellPopulationWithBuskeUpdate<2>;
00216 template class NodeBasedCellPopulationWithBuskeUpdate<3>;
00217
00218
00219 #include "SerializationExportWrapperForCpp.hpp"
00220 EXPORT_TEMPLATE_CLASS_SAME_DIMS(NodeBasedCellPopulationWithBuskeUpdate)