36 #include "OffLatticeSimulation.hpp"
38 #include <boost/make_shared.hpp>
40 #include "CellBasedEventHandler.hpp"
41 #include "ForwardEulerNumericalMethod.hpp"
42 #include "StepSizeException.hpp"
44 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
46 bool deleteCellPopulationInDestructor,
52 EXCEPTION(
"OffLatticeSimulations require a subclass of AbstractOffLatticeCellPopulation.");
56 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
59 mForceCollection.push_back(pForce);
62 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
65 mForceCollection.clear();
68 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
71 mBoundaryConditions.push_back(pBoundaryCondition);
74 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
77 mBoundaryConditions.clear();
80 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
83 mpNumericalMethod = pNumericalMethod;
86 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
89 return mpNumericalMethod;
92 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
95 return mForceCollection;
98 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
103 double time_advanced_so_far = 0;
104 double target_time_step = this->mDt;
105 double present_time_step = this->mDt;
107 while (time_advanced_so_far < target_time_step)
110 std::map<Node<SPACE_DIM>*, c_vector<double, SPACE_DIM> > old_node_locations;
113 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
116 old_node_locations[&(*node_iter)] = (node_iter)->rGetLocation();
122 mpNumericalMethod->UpdateAllNodePositions(present_time_step);
123 ApplyBoundaries(old_node_locations);
126 time_advanced_so_far += present_time_step;
129 if (mpNumericalMethod->HasAdaptiveTimestep())
132 double timestep_increase = 0.01;
133 present_time_step = std::min((1+timestep_increase)*present_time_step, target_time_step - time_advanced_so_far);
140 if (mpNumericalMethod->HasAdaptiveTimestep())
143 RevertToOldLocations(old_node_locations);
144 present_time_step = std::min(e.
GetSuggestedNewStep(), target_time_step - time_advanced_so_far);
157 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
161 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
164 (node_iter)->rGetModifiableLocation() = oldNodeLoctions[&(*node_iter)];
168 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
173 bcs_iter != mBoundaryConditions.end();
176 (*bcs_iter)->ImposeBoundaryCondition(oldNodeLoctions);
181 bcs_iter != mBoundaryConditions.end();
184 if (!((*bcs_iter)->VerifyBoundaryCondition()))
186 EXCEPTION(
"The cell population boundary conditions are incompatible.");
191 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
196 for (
unsigned i=0; i<this->mForceCollection.size(); i++)
198 this->mForceCollection[i]->WriteDataToVisualizerSetupFile(this->mpVizSetupFile);
201 this->mrCellPopulation.WriteDataToVisualizerSetupFile(this->mpVizSetupFile);
205 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
210 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
213 node_iter->ClearAppliedForce();
217 if (mpNumericalMethod ==
nullptr)
219 mpNumericalMethod = boost::make_shared<ForwardEulerNumericalMethod<ELEMENT_DIM, SPACE_DIM> >();
222 mpNumericalMethod->SetForceCollection(&mForceCollection);
225 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
229 *rParamsFile <<
"\n\t<Forces>\n";
231 iter != mForceCollection.end();
235 (*iter)->OutputForceInfo(rParamsFile);
237 *rParamsFile <<
"\t</Forces>\n";
240 *rParamsFile <<
"\n\t<CellPopulationBoundaryConditions>\n";
242 iter != mBoundaryConditions.end();
246 (*iter)->OutputCellPopulationBoundaryConditionInfo(rParamsFile);
248 *rParamsFile <<
"\t</CellPopulationBoundaryConditions>\n";
251 *rParamsFile <<
"\n\t<NumericalMethod>\n";
252 mpNumericalMethod->OutputNumericalMethodInfo(rParamsFile);
253 *rParamsFile <<
"\t</NumericalMethod>\n";
256 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
const boost::shared_ptr< AbstractNumericalMethod< ELEMENT_DIM, SPACE_DIM > > GetNumericalMethod() const
virtual const char * what() const
void OutputAdditionalSimulationSetup(out_stream &rParamsFile)
virtual void WriteVisualizerSetupFile()
virtual void SetupSolve()
#define EXCEPTION(message)
static void BeginEvent(unsigned event)
const std::vector< boost::shared_ptr< AbstractForce< ELEMENT_DIM, SPACE_DIM > > > & rGetForceCollection() const
void SetNumericalMethod(boost::shared_ptr< AbstractNumericalMethod< ELEMENT_DIM, SPACE_DIM > > pNumericalMethod)
double GetSuggestedNewStep()
void ApplyBoundaries(std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > oldNodeLoctions)
void AddForce(boost::shared_ptr< AbstractForce< ELEMENT_DIM, SPACE_DIM > > pForce)
void RemoveAllCellPopulationBoundaryConditions()
virtual void OutputSimulationParameters(out_stream &rParamsFile)=0
void RevertToOldLocations(std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > oldNodeLoctions)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
static void EndEvent(unsigned event)
OffLatticeSimulation(AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool deleteCellPopulationInDestructor=false, bool initialiseCells=true)
virtual void OutputSimulationParameters(out_stream &rParamsFile)
virtual void UpdateCellLocationsAndTopology()
void AddCellPopulationBoundaryCondition(boost::shared_ptr< AbstractCellPopulationBoundaryCondition< ELEMENT_DIM, SPACE_DIM > > pBoundaryCondition)