Root Finding

I need help with this program. No idea where to start or set up.

When a car hits a pot-hole, the springs and shocks get a workout dampening out the sudden jolt.
If the shock absorbers are working properly, the resulting oscillation is dampened quickly. Using
physics, we can establish an equation that defines the vertical motion as a function of time, x(t).
At any given point, the forces acting on the car are the resistance of the spring and the damping
force of the shock absorber. The spring force is –kx, and the dampening force is –cx' where x' is
the first derivative of x with respect to time (the vertical speed of motion). Applying Newton's
second law of motion (ΣF=ma), the equation becomes
+ = 0

′′ +
m
kx
m
xc
x
This is a second order differential equation. If the car hits a hole in the road at time t = 0 sec, and
is displaced x0 meters from its equilibrium position, the solution to the differential equation is
( cos( ) sin( )) 0 0
x e x st x st
s
nt n = +

where
m
c
n
2
= and 2
2
4m
c
m
k
s = −
and where the spring constant k = 1.25E9 g/s2
,
and the dampening coefficient c = 1.40E7 g/s,
and the mass of the car m is measured in grams,
and the depth of the hole (x0) is measured in meters.

Write a program that will find the roots of the equation shown using the bisect method. The roots
represent the times at which the oscillating wheel passes its equilibrium point. (At what times t
will x = 0?) Prompt the user for the bounds between which to search for a root. Write a
function to handle this input from the user. Also write a function to find x, given t and
name it fcn(). Hardcode as constants the values for m and x0 based on a 3000 lb car and a
10 inch pothole. Convert these measurements to the required units carefully.
The following third function is provided. Study it until you understand exactly what is does.
Then copy and append it to the end of your source file, using it to bisect the interval of any
continuous mathematical function. To use it you must pass it the left and right bounds correctly
and make proper use of the value it returns. Using it will require that you name your function
which evaluates x (given t) correctly. Do not change this bisect function—just use it as is.
bool bisect(double& left, double& right) {
if (fcn(left)*fcn(right) > 0)
return 1;
double mid = (left + right)/2;
if (fcn(left)*fcn(mid) < 0)
right = mid;
else
left = mid;
return 0;
}
If a root does not exist in the interval, output an appropriate message instead of trying to find it!
Follow the console output format shown below:
HW7 Root finding
Please enter the lower limit: 0.08
Please enter the upper limit: 0.13
The root is x.xxxxxx
Detailed results can be found in HW7Results.txt in the project folder.

Output (to a file) the record of its search in the form of a table in the format shown below.
Output the root to both file and console. Tell the user where to find the table.
iter time (left) time (right) position (left) position (right)
0 0.020000 0.080000 x.xxxxxx x.xxxxxx
1 x.xxxxxx x.xxxxxx x.xxxxxx x.xxxxxx
. . .
This output format lists the current left bound, right bound, and the equation evaluated at each of
these, for each iteration. Stop calculating when the root has been established to a precision of six
decimal digits. Test your program with these three intervals:
between t = 0.02 and 0.08
between t = 0.08 and 0.13
between t = 0.20 and 0.29
As always, do not fail to check all of your answers with hand calculations.

If anyone can help me get through this program it would be great!
Last edited on
Your link is asking me for a password.
a lot of us can't click the external links. Just post what you want to do and what you have done so far and what is giving you trouble.

Read the assignment and pick out the specific bits of code that you must write. Create pseudo-code for each one. I often use C++ comments. When you're done, read the assignment again and see if you've missed anything. Repeat the process until you're sure that have everything needed. Then you should be able to just fill in code for the comments. I'll get you started:

Prompt the user for the bounds between which to search for a root.
1
2
3
double left, right;
cout << "enter the limits: " << flush;
cin >> left >> right;

Write a function to handle this input from the user.

Oops, so that's
1
2
3
4
5
6
7
8
9
10
11
void getBounds (double &left, double &right)
{
cout << "enter the limits: " << flush;
cin >> left >> right;
}

int main()
{
double left, right;
getBounds(left,right);
...

Also write a function to find x, given t and name it fcn().
1
2
3
4
double fcn(double t)
{
    // compute x(t) and return it.
}

Hardcode as constants the values for m and x0 based on a 3000 lb car and a
10 inch pothole. Convert these measurements to the required units carefully.
1
2
const double m = 3000; // TODO: change unilts
const double x0 = 10;    // TODO: change units 

The following third function is provided. Study it until you understand exactly what is does.

So we'll need this in the code exactly as-is:
1
2
3
4
5
6
7
8
9
10
bool bisect(double& left, double& right) {
if (fcn(left)*fcn(right) > 0)
return 1;
double mid = (left + right)/2;
if (fcn(left)*fcn(mid) < 0)
right = mid;
else
left = mid;
return 0;
} 

Editorial: why the heck is the prof returning 1/0 from a bool function?? It should be true/false!
TODO: study that code and figure out what it does. Add comments.
Follow the console output format shown below...:


TODO: change the prompts in getBounds to match this:
Please enter the lower limit: 0.08
Please enter the upper limit: 0.13


So now maybe main is:
int main()
{
count << "HW7 Root finding\n";
getBounds(left, right);
cout << "The root is" << solve(left, right) << '\n';
cout << "Detailed results can be found in HW7Results.txt in the project folder.\n"
}

and solve is:
double solve(double left, double right);

Sweet! Put this together into a program. For now, just have solve() return some number. Get the program to compile and run. Now you have a program that reads the numbers and calls the solver.

Next, code up fcn() to compute the value of the function. Add some temporary code to evaluate it at a few points and check your results.

Then write code for solve(). Be sure to write the output file data. This will help you debug solve().

When you're done, re-read the assignment again. Carefully check to make sure you've done everything you're supposed to. Make sure that your output matches the requirements exactly.
1
2
3
4
#include <iostream>
int main () {
   std::cout << "potholes are caused by freezing water, not roots.\n";
}


But seriously, you're using a GHz speed computer and you're going to compute second order differential equations instead of just using basic math and simulating it on such a finely grained time resolution that you get a right answer to 6 digits of precision anyway?

Because you can do that now. You couldn't before.

If you've already worked out the calculus, you don't need C++ to solve your problem. You just need a nice calculator.
Mattrat, what are those equations supposed to be? They got garbled in your original post.
I think this is just the Hooke's law lab, but with a car instead. The wheel is never going to get a chance to oscillate I mean seriously how big are these potholes, that the car is in freefall for that long? Not to mention the fact that the wheel is round and never leaves contact with the ground in a typical pothole.

adding the car backstory is confusing what could have been a much simpler problem because the student's mental picture isn't matching with what they are being told to do with the math.

For the class, you just need to solve two Hooke's law problems. The first one is being defined as what happens when a supported mass is suddenly released and accelerated by the force of the compressed spring and gravity as well. If you need six digits of precision, you will need to model the fact that the vehicle and the tire are both in freefall and on opposite ends of the spring. (the combined center of mass experiences freefall, the two objects have opposing inertia on opposite ends of the spring)

that's where it gets silly, because in the real world, the wheel is still partially connected to the ground. but the problem doesn't make any provision for wheel angle because wheel size and vehicle speed aren't even mentioned, not to mention things like tire inflation, etc etc (it gets horribly complicated if you're making a self driving vehicle, for example)

The second one is being defined as what happens when a spring is suddenly compressed and the mass above it oscillates in response. The wheel in your lab problem is firmly planted on the ground and tire inflation isn't an issue again.
Last edited on
I should think from the description that the original equation is
m d2x/dt2 = -k x - c dx/dt

or
m d2x/dt2 + c dx/dt + k x = 0


If it's underdamped it will undergo decaying oscillations:
x = e-st( A sin nt + B cos nt )

where
s = c/(2m),
n = sqrt( k/m - s2 )


A and B depend on initial conditions, so would probably be
A = sx0/n and B = x0
Last edited on
Topic archived. No new replies allowed.