36#include "AbstractNumericalMethod.hpp"
37#include "StepSizeException.hpp"
38#include "Warnings.hpp"
39#include "NodeBasedCellPopulationWithBuskeUpdate.hpp"
40#include "ImmersedBoundaryCellPopulation.hpp"
41#include "MeshBasedCellPopulationWithGhostNodes.hpp"
42#include "CellBasedEventHandler.hpp"
44template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
46 : mpCellPopulation(nullptr),
47 mpForceCollection(nullptr),
48 mUseAdaptiveTimestep(false),
49 mGhostNodeForcesEnabled(true)
54template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
59template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
62 mpCellPopulation = pPopulation;
67 bool population_requires_delegation =
71 if (population_requires_delegation != this->DelegatesToPopulation())
73 EXCEPTION(
"NoNumericalMethod must be used if and only if the cell population manages its own "
74 "node position updates (currently NodeBasedCellPopulationWithBuskeUpdate and "
75 "ImmersedBoundaryCellPopulation).");
80 mGhostNodeForcesEnabled =
true;
84 mGhostNodeForcesEnabled =
false;
88template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
91 mpForceCollection = pForces;
94template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
97 mpBoundaryConditions = pBoundaryConditions;
100template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
103 mUseAdaptiveTimestep = useAdaptiveTimestep;
106template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
109 return mUseAdaptiveTimestep;
112template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
115 std::map<Node<SPACE_DIM>*, c_vector<double, SPACE_DIM> > node_locations;
118 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd();
121 node_locations[&(*node_iter)] = (node_iter)->rGetLocation();
124 return node_locations;
127template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
132 bcs_iter != mpBoundaryConditions->end();
135 (*bcs_iter)->ImposeBoundaryCondition(rOldNodeLocations);
139template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
145 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd(); ++node_iter)
147 node_iter->ClearAppliedForce();
151 iter != mpForceCollection->end(); ++iter)
153 (*iter)->AddForceContribution(*mpCellPopulation);
162 if (mGhostNodeForcesEnabled)
168 std::vector<c_vector<double, SPACE_DIM> > forces_as_vector;
169 forces_as_vector.reserve(mpCellPopulation->GetNumNodes());
172 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd(); ++node_iter)
174 double damping = mpCellPopulation->GetDampingConstant(node_iter->GetIndex());
175 forces_as_vector.push_back(node_iter->rGetAppliedForce()/damping);
180 return forces_as_vector;
183template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
186 std::vector<c_vector<double, SPACE_DIM> > current_locations;
187 current_locations.reserve(mpCellPopulation->GetNumNodes());
190 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd();
193 current_locations.push_back(node_iter->rGetLocation());
196 return current_locations;
199template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
203 mpCellPopulation->SetNode(nodeIndex, new_point);
206template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
211 mpCellPopulation->CheckForStepSizeException(nodeIndex, displacement, dt);
215 if (!(e.IsTerminal()) && (mUseAdaptiveTimestep==
false))
222 WARN_ONCE_ONLY(e.what());
231template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
237template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
240 std::string numerical_method_type = GetIdentifier();
242 *rParamsFile <<
"\t\t<" << numerical_method_type <<
">\n";
243 OutputNumericalMethodParameters(rParamsFile);
244 *rParamsFile <<
"\t\t</" << numerical_method_type <<
">\n";
247template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
250 *rParamsFile <<
"\t\t\t<UseAdaptiveTimestep>" << mUseAdaptiveTimestep <<
"</UseAdaptiveTimestep> \n";
251 *rParamsFile <<
"\t\t\t<DelegatesToPopulation>" << this->DelegatesToPopulation() <<
"</DelegatesToPopulation> \n";
252 *rParamsFile <<
"\t\t\t<GhostNodeForcesEnabled>" << mGhostNodeForcesEnabled <<
"</GhostNodeForcesEnabled> \n";
#define EXCEPTION(message)
void SetForceCollection(std::vector< boost::shared_ptr< AbstractForce< ELEMENT_DIM, SPACE_DIM > > > *pForces)
bool HasAdaptiveTimestep()
std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > SaveCurrentNodeLocations()
void SetCellPopulation(AbstractOffLatticeCellPopulation< ELEMENT_DIM, SPACE_DIM > *pPopulation)
void SafeNodePositionUpdate(unsigned nodeIndex, c_vector< double, SPACE_DIM > newPosition)
void ImposeBoundaryConditions(std::map< Node< SPACE_DIM > *, c_vector< double, SPACE_DIM > > &rOldNodeLocations)
void OutputNumericalMethodInfo(out_stream &rParamsFile)
void DetectStepSizeExceptions(unsigned nodeIndex, c_vector< double, SPACE_DIM > &displacement, double dt)
AbstractNumericalMethod()
virtual void SetUseAdaptiveTimestep(bool useAdaptiveTimestep)
void SetBoundaryConditions(std::vector< boost::shared_ptr< AbstractCellPopulationBoundaryCondition< ELEMENT_DIM, SPACE_DIM > > > *pBoundaryConditions)
std::vector< c_vector< double, SPACE_DIM > > ComputeForcesIncludingDamping()
std::vector< c_vector< double, SPACE_DIM > > SaveCurrentLocations()
virtual ~AbstractNumericalMethod()
virtual bool DelegatesToPopulation()
virtual void OutputNumericalMethodParameters(out_stream &rParamsFile)
static void BeginEvent(unsigned event)
static void EndEvent(unsigned event)