36 #include "DiscreteSystemForceCalculator.hpp"
40 : mrCellPopulation(rCellPopulation),
41 mForceCollection(forceCollection),
50 std::vector< std::vector<double> > extremal_normal_forces;
51 std::vector<double> minimum_normal_forces(num_nodes);
52 std::vector<double> maximum_normal_forces(num_nodes);
54 for (
unsigned i=0; i<num_nodes; i++)
59 double minimum_normal_force_for_node_i = DBL_MAX;
60 double maximum_normal_force_for_node_i = -DBL_MAX;
62 for (
unsigned j=0; j<extremal_angles.size(); j++)
66 if (current_normal_force > maximum_normal_force_for_node_i)
68 maximum_normal_force_for_node_i = current_normal_force;
70 if (current_normal_force < minimum_normal_force_for_node_i)
72 minimum_normal_force_for_node_i = current_normal_force;
76 assert( minimum_normal_force_for_node_i <= maximum_normal_force_for_node_i);
78 minimum_normal_forces[i] = minimum_normal_force_for_node_i;
79 maximum_normal_forces[i] = maximum_normal_force_for_node_i;
82 extremal_normal_forces.push_back(minimum_normal_forces);
83 extremal_normal_forces.push_back(maximum_normal_forces);
85 return extremal_normal_forces;
91 std::ostringstream time_string;
93 std::string results_directory = simulationOutputDirectory +
"/results_from_time_" + time_string.str();
98 (*mpVizStressResultsFile) << time <<
"\t";
112 global_index = (
double) i;
114 x = r_mesh.
GetNode(i)->rGetLocation()[0];
115 y = r_mesh.
GetNode(i)->rGetLocation()[1];
117 minimum = extremal_normal_forces[0][i];
118 maximum = extremal_normal_forces[1][i];
120 (*mpVizStressResultsFile) << global_index <<
" " << x <<
" " << y <<
" " << minimum <<
" " << maximum <<
" ";
123 (*mpVizStressResultsFile) <<
"\n";
133 double tangential_force = 0.0;
134 double normal_force = 0.0;
137 c_vector<double,2> unit_vec_between_nodes(2);
139 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
140 iter != neighbouring_node_indices.end();
146 assert(alpha <= M_PI);
147 assert(alpha > -M_PI);
149 if (sin(alpha-theta) > DBL_EPSILON)
152 c_vector<double,2> force_between_nodes = zero_vector<double>(2);
159 force_between_nodes += (*force_iter)->CalculateForceBetweenNodes(index, *iter,
mrCellPopulation);
162 unit_vec_between_nodes[0] = cos(alpha);
163 unit_vec_between_nodes[1] = sin(alpha);
165 double plusminus_norm_force = inner_prod(force_between_nodes,unit_vec_between_nodes);
166 tangential_force += plusminus_norm_force * cos(alpha-theta);
167 normal_force += plusminus_norm_force * sin(alpha-theta);
171 std::vector<double> ret(2);
172 ret[0] = tangential_force;
173 ret[1] = normal_force;
184 std::vector<double> sampling_angles(4*neighbouring_node_indices.size());
188 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
189 iter != neighbouring_node_indices.end();
195 double alpha_minus_epsilon = alpha -
mEpsilon;
196 double alpha_plus_epsilon = alpha +
mEpsilon;
197 double alpha_plus_pi_minus_epsilon = alpha + M_PI -
mEpsilon;
198 double alpha_plus_pi_plus_epsilon = alpha + M_PI +
mEpsilon;
202 #define COVERAGE_IGNORE
203 if (alpha_minus_epsilon <= -M_PI)
205 alpha_minus_epsilon += 2*M_PI;
207 #undef COVERAGE_IGNORE
208 sampling_angles[i] = alpha_minus_epsilon;
210 assert(sampling_angles[i] <= M_PI);
211 assert(sampling_angles[i] > -M_PI);
214 if (alpha_plus_epsilon > M_PI)
216 alpha_plus_epsilon -= 2*M_PI;
218 sampling_angles[i] = alpha_plus_epsilon;
220 assert(sampling_angles[i] <= M_PI);
221 assert(sampling_angles[i] > -M_PI);
224 if (alpha_plus_pi_minus_epsilon > M_PI)
226 alpha_plus_pi_minus_epsilon -= 2*M_PI;
228 sampling_angles[i] = alpha_plus_pi_minus_epsilon;
230 assert(sampling_angles[i] <= M_PI);
231 assert(sampling_angles[i] > -M_PI);
234 if (alpha_plus_pi_plus_epsilon > M_PI)
236 alpha_plus_pi_plus_epsilon -= 2*M_PI;
238 sampling_angles[i] = alpha_plus_pi_plus_epsilon;
240 assert(sampling_angles[i] <= M_PI);
241 assert(sampling_angles[i] > -M_PI);
245 sort(sampling_angles.begin(), sampling_angles.end());
246 return sampling_angles;
253 assert(angle1 < angle2);
255 double tolerance = 1e-5;
256 unsigned counter = 0;
258 double previous_angle;
259 double current_error;
260 double current_angle = angle1;
262 current_error = angle2 - angle1;
263 std::vector<double> current_ft_and_fn(2);
265 while (current_error > tolerance)
267 previous_angle = current_angle;
269 current_angle -= current_ft_and_fn[0]/current_ft_and_fn[1];
270 current_error = fabs(current_angle - previous_angle);
274 assert(current_angle>angle1 && current_angle<angle2);
275 assert(current_error < tolerance);
277 return current_angle;
282 std::vector<double> extremal_angles;
283 std::vector<double> ft_and_fn(2);
284 std::vector<double> tangential_force(samplingAngles.size());
286 for (
unsigned i=0; i<samplingAngles.size(); i++)
289 tangential_force[i] = ft_and_fn[0];
292 unsigned n = samplingAngles.size()-1;
294 for (
unsigned i=0; i<n; i++)
296 if ( ( tangential_force[i%n]>0 && tangential_force[(i+1)%n]<0 ) ||
297 ( tangential_force[i%n]<0 && tangential_force[(i+1)%n]>0 ) )
299 double next_extremal_angle;
305 samplingAngles[i%n] -= 2*M_PI;
308 if (samplingAngles[(i+1)%n] - samplingAngles[i%n] < 2*
mEpsilon + 1e-6 )
312 next_extremal_angle = 0.5*(samplingAngles[(i+1)%n] + samplingAngles[i%n]);
317 next_extremal_angle =
GetLocalExtremum(index, samplingAngles[i%n], samplingAngles[(i+1)%n]);
320 if (next_extremal_angle <= -M_PI)
322 next_extremal_angle += 2*M_PI;
324 assert(next_extremal_angle>-M_PI && next_extremal_angle<=M_PI);
325 extremal_angles.push_back(next_extremal_angle);
329 return extremal_angles;
double GetAngleBetweenNodes(unsigned indexA, unsigned indexB)
DiscreteSystemForceCalculator(MeshBasedCellPopulation< 2 > &rCellPopulation, std::vector< boost::shared_ptr< AbstractTwoBodyInteractionForce< 2 > > > forceCollection)
out_stream mpVizStressResultsFile
std::vector< double > GetSamplingAngles(unsigned index)
Node< SPACE_DIM > * GetNode(unsigned index) const
static SimulationTime * Instance()
std::vector< boost::shared_ptr< AbstractTwoBodyInteractionForce< 2 > > > mForceCollection
virtual unsigned GetNumNodes() const
MutableMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
void WriteResultsToFile(std::string simulationOutputDirectory)
double GetLocalExtremum(unsigned index, double angle1, double angle2)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
std::vector< double > CalculateFtAndFn(unsigned index, double theta)
std::vector< double > GetExtremalAngles(unsigned index, std::vector< double > samplingAngles)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned index)
MeshBasedCellPopulation< 2 > & mrCellPopulation
std::vector< std::vector< double > > CalculateExtremalNormalForces()