36#include "OffLatticeSimulation.hpp"
38#include <boost/make_shared.hpp>
40#include "CellBasedEventHandler.hpp"
41#include "ForwardEulerNumericalMethod.hpp"
42#include "StepSizeException.hpp"
44template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
46 bool deleteCellPopulationInDestructor,
52 EXCEPTION(
"OffLatticeSimulations require a subclass of AbstractOffLatticeCellPopulation.");
56template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
59 mForceCollection.push_back(pForce);
62template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
65 mForceCollection.clear();
68template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
71 mBoundaryConditions.push_back(pBoundaryCondition);
74template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
77 mBoundaryConditions.clear();
80template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
83 mpNumericalMethod = pNumericalMethod;
86template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
89 return mpNumericalMethod;
92template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
95 return mForceCollection;
98template<
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);
157template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
161 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
164 (node_iter)->rGetModifiableLocation() = oldNodeLoctions[&(*node_iter)];
168template<
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.");
191template<
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);
205template<
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);
223 mpNumericalMethod->SetBoundaryConditions(&mBoundaryConditions);
226template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
230 *rParamsFile <<
"\n\t<Forces>\n";
232 iter != mForceCollection.end();
236 (*iter)->OutputForceInfo(rParamsFile);
238 *rParamsFile <<
"\t</Forces>\n";
241 *rParamsFile <<
"\n\t<CellPopulationBoundaryConditions>\n";
243 iter != mBoundaryConditions.end();
247 (*iter)->OutputCellPopulationBoundaryConditionInfo(rParamsFile);
249 *rParamsFile <<
"\t</CellPopulationBoundaryConditions>\n";
252 *rParamsFile <<
"\n\t<NumericalMethod>\n";
253 mpNumericalMethod->OutputNumericalMethodInfo(rParamsFile);
254 *rParamsFile <<
"\t</NumericalMethod>\n";
257template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
#define EXCEPTION(message)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual void OutputSimulationParameters(out_stream &rParamsFile)=0
static void BeginEvent(unsigned event)
static void EndEvent(unsigned event)
const boost::shared_ptr< AbstractNumericalMethod< ELEMENT_DIM, SPACE_DIM > > GetNumericalMethod() const
virtual void UpdateCellLocationsAndTopology()
void OutputAdditionalSimulationSetup(out_stream &rParamsFile)
void RemoveAllCellPopulationBoundaryConditions()
void AddCellPopulationBoundaryCondition(boost::shared_ptr< AbstractCellPopulationBoundaryCondition< ELEMENT_DIM, SPACE_DIM > > pBoundaryCondition)
const std::vector< boost::shared_ptr< AbstractForce< ELEMENT_DIM, SPACE_DIM > > > & rGetForceCollection() const
void SetNumericalMethod(boost::shared_ptr< AbstractNumericalMethod< ELEMENT_DIM, SPACE_DIM > > pNumericalMethod)
virtual void SetupSolve()
void ApplyBoundaries(std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > oldNodeLoctions)
virtual void WriteVisualizerSetupFile()
virtual void OutputSimulationParameters(out_stream &rParamsFile)
void RevertToOldLocations(std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > oldNodeLoctions)
void AddForce(boost::shared_ptr< AbstractForce< ELEMENT_DIM, SPACE_DIM > > pForce)
OffLatticeSimulation(AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool deleteCellPopulationInDestructor=false, bool initialiseCells=true)