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