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>
101 mMaxAdaptiveTimeSteps = maxAdaptiveTimeStep;
104template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
107 return mMaxAdaptiveTimeSteps;
110template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
115 double time_advanced_so_far = 0;
116 double target_time_step = this->mDt;
117 double present_time_step = this->mDt;
119 unsigned adaptive_timer = 0;
120 while (time_advanced_so_far < target_time_step)
123 std::map<Node<SPACE_DIM>*, c_vector<double, SPACE_DIM> > old_node_locations;
125 for (
auto node_iter = this->mrCellPopulation.rGetMesh().GetNodeIteratorBegin();
126 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
129 old_node_locations[&(*node_iter)] = (node_iter)->rGetLocation();
135 mpNumericalMethod->UpdateAllNodePositions(present_time_step);
136 ApplyBoundaries(old_node_locations);
139 time_advanced_so_far += present_time_step;
145 if (mpNumericalMethod->HasAdaptiveTimestep() && adaptive_timer < mMaxAdaptiveTimeSteps)
148 RevertToOldLocations(old_node_locations);
149 present_time_step = std::min(e.GetSuggestedNewStep(), target_time_step - time_advanced_so_far);
163template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
167 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
170 (node_iter)->rGetModifiableLocation() = oldNodeLoctions[&(*node_iter)];
174template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
179 bcs_iter != mBoundaryConditions.end();
182 (*bcs_iter)->ImposeBoundaryCondition(oldNodeLoctions);
187 bcs_iter != mBoundaryConditions.end();
190 if (!((*bcs_iter)->VerifyBoundaryCondition()))
192 EXCEPTION(
"The cell population boundary conditions are incompatible.");
197template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
202 for (
unsigned i=0; i<this->mForceCollection.size(); i++)
204 this->mForceCollection[i]->WriteDataToVisualizerSetupFile(this->mpVizSetupFile);
207 this->mrCellPopulation.WriteDataToVisualizerSetupFile(this->mpVizSetupFile);
211template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
216 node_iter != this->mrCellPopulation.rGetMesh().GetNodeIteratorEnd();
219 node_iter->ClearAppliedForce();
223 if (mpNumericalMethod ==
nullptr)
225 mpNumericalMethod = boost::make_shared<ForwardEulerNumericalMethod<ELEMENT_DIM, SPACE_DIM> >();
228 mpNumericalMethod->SetForceCollection(&mForceCollection);
229 mpNumericalMethod->SetBoundaryConditions(&mBoundaryConditions);
232template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
236 *rParamsFile <<
"\n\t<Forces>\n";
238 iter != mForceCollection.end();
242 (*iter)->OutputForceInfo(rParamsFile);
244 *rParamsFile <<
"\t</Forces>\n";
247 *rParamsFile <<
"\n\t<CellPopulationBoundaryConditions>\n";
249 iter != mBoundaryConditions.end();
253 (*iter)->OutputCellPopulationBoundaryConditionInfo(rParamsFile);
255 *rParamsFile <<
"\t</CellPopulationBoundaryConditions>\n";
258 *rParamsFile <<
"\n\t<NumericalMethod>\n";
259 mpNumericalMethod->OutputNumericalMethodInfo(rParamsFile);
260 *rParamsFile <<
"\t</NumericalMethod>\n";
263template<
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
unsigned GetMaxAdaptiveTimeStep() const
virtual void UpdateCellLocationsAndTopology()
void OutputAdditionalSimulationSetup(out_stream &rParamsFile)
void RemoveAllCellPopulationBoundaryConditions()
void AddCellPopulationBoundaryCondition(boost::shared_ptr< AbstractCellPopulationBoundaryCondition< ELEMENT_DIM, SPACE_DIM > > pBoundaryCondition)
void SetMaxAdaptiveTimeStep(unsigned maxAdaptiveTimeStep)
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)