36#include "AbstractNumericalMethod.hpp"
37#include "StepSizeException.hpp"
38#include "Warnings.hpp"
39#include "AbstractCentreBasedCellPopulation.hpp"
40#include "NodeBasedCellPopulationWithBuskeUpdate.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 mUseUpdateNodeLocation(false),
50 mGhostNodeForcesEnabled(true)
55template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
60template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
63 mpCellPopulation = pPopulation;
68 mUseUpdateNodeLocation =
true;
69 WARNING(
"Non-Euler steppers are not yet implemented for NodeBasedCellPopulationWithBuskeUpdate");
74 mGhostNodeForcesEnabled =
true;
78 mGhostNodeForcesEnabled =
false;
82template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
85 mpForceCollection = pForces;
88template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
91 mpBoundaryConditions = pBoundaryConditions;
94template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
97 mUseAdaptiveTimestep = useAdaptiveTimestep;
100template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
103 return mUseAdaptiveTimestep;
106template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
109 std::map<Node<SPACE_DIM>*, c_vector<double, SPACE_DIM> > node_locations;
112 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd();
115 node_locations[&(*node_iter)] = (node_iter)->rGetLocation();
118 return node_locations;
121template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
126 bcs_iter != mpBoundaryConditions->end();
129 (*bcs_iter)->ImposeBoundaryCondition(rOldNodeLocations);
133template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
139 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd(); ++node_iter)
141 node_iter->ClearAppliedForce();
145 iter != mpForceCollection->end(); ++iter)
147 (*iter)->AddForceContribution(*mpCellPopulation);
156 if (mGhostNodeForcesEnabled)
162 std::vector<c_vector<double, SPACE_DIM> > forces_as_vector;
163 forces_as_vector.reserve(mpCellPopulation->GetNumNodes());
166 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd(); ++node_iter)
168 double damping = mpCellPopulation->GetDampingConstant(node_iter->GetIndex());
169 forces_as_vector.push_back(node_iter->rGetAppliedForce()/damping);
174 return forces_as_vector;
177template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
180 std::vector<c_vector<double, SPACE_DIM> > current_locations;
181 current_locations.reserve(mpCellPopulation->GetNumNodes());
184 node_iter != mpCellPopulation->rGetMesh().GetNodeIteratorEnd();
187 current_locations.push_back(node_iter->rGetLocation());
190 return current_locations;
193template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
197 mpCellPopulation->SetNode(nodeIndex, new_point);
200template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
205 mpCellPopulation->CheckForStepSizeException(nodeIndex, displacement, dt);
209 if (!(e.IsTerminal()) && (mUseAdaptiveTimestep==
false))
216 WARN_ONCE_ONLY(e.what());
225template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
228 mUseUpdateNodeLocation = useUpdateNodeLocation;
231template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
234 return mUseUpdateNodeLocation;
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<UseUpdateNodeLocation>" << mUseUpdateNodeLocation <<
"</UseUpdateNodeLocation> \n";
252 *rParamsFile <<
"\t\t\t<GhostNodeForcesEnabled>" << mGhostNodeForcesEnabled <<
"</GhostNodeForcesEnabled> \n";
bool GetUseUpdateNodeLocation()
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()
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()
void SetUseUpdateNodeLocation(bool useUpdateNodeLocation)
std::vector< c_vector< double, SPACE_DIM > > SaveCurrentLocations()
virtual ~AbstractNumericalMethod()
virtual void OutputNumericalMethodParameters(out_stream &rParamsFile)
static void BeginEvent(unsigned event)
static void EndEvent(unsigned event)