Physics 238—Intermediate Physics Lab Homework Assignment #3 Due Friday, March 14, 2025, 1:15 p.m.

In the torsional oscillator experiment, you found that the linear damping model did not describe the trial with air drag very well. In this assignment, you will see how to use Mathematicaxto numerically integrate the equations of motion, and then use that model to fit your data with air drag.

This work is presented here as a sequence of assignments. If you find it convenient, you may simply turn in one Mathematicaxnotebook with your results, but please trim out irrelevant material before printing and submitting it.

This assignment is fairly long; it will be weighted as two homework assignments.

1 The Simple Harmonic Oscillator Consider a mass m attached to an ideal horizontal spring with spring constant k. The differential equation governing the motion is then simply

. mẍ = −kx .

(1)

Take the initial conditions to be x(0) = x_{0} and x(0) = v_{0}. Your goal is to follow the evolution of the system with time, for times running from 0 to 10 seconds.

To be concrete, take the following numerical values:

11 Variable 11 Value 11 Units 11 Description
11 k  11 1.5  11 N/m 11 Spring constant
11 m  11 0.08 11 kg  11 Mass, 80 g.
11 x_{0}  11 0.80 11 m  11 Initial position
11 v_{0}  11 0.0  11 m/s 11 Initial velocity
11 tstop  11 10  11 s  11 Total time to run

11

1.1 Setting up the Simulation Start Mathematica. Put a title at the top of your notebook. (Use the Format → Style menu. “Title” is rather large; feel free to pick something smaller.)

Put your name in a text cell near the top. Also give the date. (The command DateString[] is handy for this.) I also find it convenient to start each notebook with Clear["Global`*"] to erase any possible lingering definitions from earlier work.

Add in the physical constants:

xxxxkx=x1.5x(*xSpringxconstantx*);
xxxxmx=x0.08x(*xmassx*);

You can add an in-line comment in Mathematicaxby enclosing text in (* and *). This is a helpful way to document your variables. Note too the trailing semicolon—it keeps Mathematicaxfrom printing out the result of each line.

It is also handy to add in a definition for the expected angular frequency and period,

\begin{aligned}ω & = \sqrt{\frac{k}{m}} \\ T & = \frac{2π}{ω} . \end{aligned}

(You can enter the square root either by using the Classroom Palette or by typing Sqrt[k/m]. You can enter π by typing Pi, by using the Classroom Palette, or by the keyboard

shortcut Escape p Escape.)

1.2 Numerical Integration Although it is possible to solve Eq.x1 analytically, that won’t always be the case. Fortunately, it is also possible to approximate the solution numerically.

Mathematicaxhas a built-in function, NDSolveValue, that handles numerical integration very efficiently. It chooses the numerical method and optimal step size automatically, and simply returns a function that you can evaluate to find the result. You can use it as follows:

xxxxx0x=x0.8x(*xInitialxpositionx*);
xxxxv0x=x0x(*xInitialxvelocityx*);
xxxxtstopx=x10x(*xTotalxtimextoxrunx*);
xxxxshmx=xNDSolveValue[
xxxxxxxx{mxx''[t]x==x-kxx[t],xx[0]x==xx0,xx'[0]x==xv0},
xxxxxxxxxx,
xxxxxxxx{t,x0,xtstop}
xxxx]

The NDSolveValue function takes three arguments, separated by commas and enclosed in square brackets. Since the arguments are fairly long, this example breaks them across several lines—one line for each argument. The first argument (in curly braces) is the list of equations to solve, including any boundary conditions. Note that in Mathematica, x'[t] means to take a derivative of x[t]. Note too that the equations are written with a double equals

sign.1 1For more details, see Equal in the online help. Click on the Details triangle and note the first entry: lhs == rhs is used to represent a symbolic equation, to be manipulated using functions like Solve. The second argument tells NDSolveValue what to solve for, and the third tells it the independent variable (t) and over what time interval to run the integration. The answer is returned as a function (shm[t]) that can be evaluated and plotted.

Copy and Paste Warning:

You are encouraged to copy and paste code from this document, but you might have to manually make some small edits. For example, the derivatives in x'[t] and x''[t] are made with the single quote key on the keyboard, but some software may render them as “smart quotes” instead. If you get a syntax error, try deleting the quote marks and re-typing them in by hand.

1.3 Results Please give each assignment an appropriate header in your notebook (e.g. by selecting a reasonable entry from the Format → Style menu). Please make sure all graphs have appropriate labels. Any comments may be inserted using text cells.

Assignment 1: Plot the result for x(t) for t = 0 to 10 s. You can do that with a simple command such as

xxxxPlot[shm[t],x{t,x0,xtstop}]

You should get a cosine function that oscillates between 0.8 and −0.8.

This simple plot is fine for trying things out, but when you are preparing a plot for presentation or submission, you should make sure the axes are labeled, and that each plot either has a label or is described by an appropriate caption in your final document. Most graphs also include a frame around the whole plot. The default font used by Mathematicaxfor the axis labels is also quite small, and is often hard to read. Finally, it is often helpful to make the plot larger; this example makes it 70% of the page width.

xxxxPlot[shm[t],x{t,x0,xtstop},
xxxxxxxxPlotLabelx->x"SimplexHarmonicxMotion",
xxxxxxxxLabelStylex->xLarger,xFramex->xTrue,
xxxxxxxxFrameLabelx->x{"tx(s)",x"xx(m)"},xImageSizex->xScaled[0.7]]

In the interest of saving space, examples in this writeup will not show these options every time, but you should include them as needed before submitting your final noteboook.

Assignment 2: In this problem, you can also compute the motion analytically,

. x_{analytic}(t) = x_{0} cos(ωt) .

Compute the analytic prediction for x(10) and compare to Mathematica’s value shm[10]. Do they agree? If not, how much do they differ by?

2 Adding Linear Damping Next, you will consider what happens if you add a linear damping term, also known as viscous damping. Specifically, consider the new equation . mẍ = −kx − bẋ ,

(2)

where b is the damping coefficient.

Assignment 3: Set b = 0.1 Ns/m and solve Eq.x2 for the resulting motion. Call your answer damped[t]. Plot the result for x(t) for t = 0 to 10 s. Note that Mathematicaxtries to zoom in on the “interesting” part of the graph. You should force Mathematicaxto show the full range by adding the option PlotRange->All. Also add in appropriate axis labels.

3 Adding Quadratic Damping Finally, you will consider a different model for damping, namely quadratic damping. This would be appropriate for resistance due to air drag, for example.

Specifically, consider the new equation

. mẍ = −kx − c|ẋ|ẋ ,

(3)

where c is a constant. (The combination −|x|x has the magnitude of v^{2}, but always has a sign opposite v, so that the drag force opposes the motion.) In Mathematica, you can take the absolute value with the Abs[ ] function.

Assignment 4: Set c = 0.1 Ns^{2}/m^{2} and solve Eq.x3 for the resulting motion. Call your answer airdrag[t]. Plot airdrag[t] vs.xt for t = 0 to 10 s. On the same graph, include the result for viscous drag from the previous part. One way to plot two functions at once is by giving the Plot command a list of functions (enclosed in curly braces) instead of just a single function:

xxxxPlot[{damped[t],xairdrag[t]},x{t,x0,xtstop},
xxxxxxxxxxPlotLegendsx->x{"Viscousxdamping",x"Airxdrag"}]

When you have more than one plot, it is important to label them. The PlotLegends option does that. It takes a list of plot labels (enclosed in curly braces)—one label for each plot. As always, add in appropriate readable labels.

Assignment 5: Comment on the qualitative differences between linear and quadratic damping. Do they correspond to what you observed in the torsional oscillator experiment?

   4 Using NDSolve with NonlinearModelFit

Lastly, you will use Mathematicaxto fit Eq.x3 to your data from the torsional oscillator experiment where the drag was provided by the air paddles. Specifically, assume that the differential equation is

.  θ̈(t) = −ω_{0}^{2} (θ(t) − θ_{off}) − c |θ̇(t)| θ̇(t)

(4) subject to the initial conditions θ(0) = θ_{0} and θ̇(0) = v_{0}. (The constant θ_{off} accounts for the fact that the voltage was not exactly zero when the oscillator was at equilibrium.)

You will use NonlinearModelFit to fit Eq.x4 to your data. There are actually 5 fit parameters: 3 for the differential equation: ω_{0}, θ_{off}, c, and two for the initial conditions: θ_{0} and v_{0}.

Roughly speaking, the plan is to use NonlinearModelFit to apply the principle of least squares. That is, you will pick a particular set of parameters, and Mathematicaxwill use NDSolveValue to create a model solution, and evaluate χ^{2} for that model. Then Mathematicaxwill try varying one (or more) of the parameters slightly to see if χ^{2} increases or decreases, and continue varying parameters until a minimum is found.

You have already seen how NonlinearModelFit sometimes needs help finding sensible starting guesses for this process. A second challenge in this problem is that Mathematicaxwill tend to keep calling NDSolveValue over and over again with the same parameters to calculate χ^{2} such that the process becomes unreasonably slow. Fortunately, there is a variant function called ParametricNDSolveValue that avoids this problem by temporarily storing (or “caching”) computed solutions. (This use of ParametricNDSolveValue is suggested in the NonlinearModelFit help page. See the first example under “Generalizations & Extensions”.)

To get started, perform the following steps:

1. Import your data for the torsional oscillator with air paddles. Apply your voltage calibration to generate a plot of angle vs.xtime. If you call your data “data”, then you can assign that plot to a variable called dataPlot with a command like the following:

xxxxdataPlotx=xListPlot[data,xPlotStylex->xRed,xPlotRangex->xAll,
xxxxxxxxxxxxxxxxLabelStylex->xLarger,
xxxxxxxxxxxxxxxxAxesLabelx->x{"tx(s)",x"Anglex(radians)"},
xxxxxxxxxxxxxxxxImageSizex->xScaled[0.8]];

You do not need to print the plot just yet.

2. Enter the model for motion with air drag. The syntax is a bit odd, but the following command should work:

Clear[\[Omega]0,xc,x\[Theta]0,xv0,x\[Theta]off]
airdragx=
xParametricNDSolveValue[
xxxx{x\[Theta]''[t]x==x-x\[Omega]0^2x(x\[Theta][t]x-x\[Theta]offx)x-
xxxxxxxxxxxxxxxxxxxxxxxxxcxAbs[\[Theta]'[t]]x\[Theta]'[t],
xxxxxx\[Theta][0]x==x\[Theta]0,x\[Theta]'[0]x==xv0
xxxx},
xxxx\[Theta],
xxx{t,x0,x30},x{\[Omega]0,xc,x\[Theta]0,xv0,x\[Theta]off}]

The first line ensures that any earlier definitions of the parameters from previous assignments are cleared. Note that you can enter θ directly; the form shown here is the plain text input form. If you copy and paste this code, Mathematicaxought to insert the θ for you. Note too that many PDF renderers will change the single quote marks to “Smart” quotes, and you may have to manually change them back to single quote marks.

3. The syntax for using airdrag is a bit odd, so it is important to test your model with some simple inputs. In general, you would type airdrag[ω_{0}, c, θ_{0}, v_{0}, θ_{off}][t]. So, for example, to evaluate the model for ω_{0} = 2.5, c = 0.5, initial position θ_{0} = 0.7, initial velocity v_{0} = −0.02 offset θ_{off} = 0.1, and time t = 12, you would type airdrag[2.5, 0.5, 0.7, -0.02, 0.1][12] That should yield 0.106687. If you wanted to plot the solution for those parameters, for t from 0 to 30 s, you would type

xxxxPlot[airdrag[2.5,x0.5,x0.7,x-0.02,x0.1][t],x{t,x0,x30}]

Assignment 6: It is important to start with reasonable guesses for all the parameters. The Manipulate function is handy for this. Try the following command:

Manipulate[
xxxxShow[{
xxxxxxxxdataPlot,
xxxxxxxxPlot[airdrag[\[Omega]0,xc,x\[Theta]0,xv0,x0][t],x{t,x0,x30},
xxxxxxxxxxxxPlotRangex->xAll]
xxxx}],
xxxx{{\[Omega]0,x2.5},x2.0,x3.0,x0.01,xAppearancex->x"Labeled"},
xxxx{{c,x0.5},x0.1,x2.0,x0.05,xAppearancex->x"Labeled"},
xxxx{{\[Theta]0,x0.5},x-1,x1,x0.05,xAppearancex->x"Labeled"},
xxxx{{v0,x0},x-4,x4,x0.05,xAppearancex->x"Labeled"}
x]

This command will produce a plot showing the data (which you made earlier) and the airdrag model, along with sliders allowing you to control 4 parameters: ω_{0}, c, θ_{0}, and v_{0}. (For simplicity, this plot sets θ_{off} = 0. You may adjust that manually if needed.) Each slider is controlled by a list (inside curly braces) of settings. For example,

xxxx{{c,x0.5},x0.1,x2.0,x0.05,xAppearancex->x"Labeled"}

will give the c parameter an initial value of 0.5, and vary it between 0.1 and 2.0 in steps of 0.05. The Appearance -> "Labeled" command means the value for the parameter will appear as a label to the right of the slider. A small + sign next to the slider opens up additional controls.

Adjust the sliders to get a reasonable first guess at a fit. Adjust the ranges in the Manipulate command if you need to. List your parameters here.

Assignment 7: Now that you have a reasonable first guess at the fit parameters, you can use them to run NonlinearModelFit. The syntax is similar to what you have used before, but it is important to remember that the model gets input as

xxxxairdrag[\[Omega]0,xc,x\[Theta]0,xv0,x\[Theta]off][t]

You will probably see some warning messages, but if Mathematicaxis successful, you will get a FittedModel output. Test your result with a plot:

xxxxShow[{dataPlot,xPlot[airdragFit[t],x{t,x0,x30},xPlotRangex->xAll]}]

Adjust your initial guesses until you are satisfied with the fit. Include the graph with the fit overlaying the data in your final submission.

Assignment 8: List the fit parameters, along with their uncertainties. (The "ParameterConfidenceIntervalTable" is appropriate here.) Again, you may see some warning messages, but if the fit looks good you may ignore them.

Assignment 9: Find the root mean square error (RMSE) for the fit. Note that the units are radians. Is your value reasonable for the fit? Do you note any significant systematic errors?

Assignment 10: Consider the correlation between the different parameters. A useful way to

display this is with MatrixForm[airdragFit["CorrelationMatrix"]]. Are there any large

correlations? (You may ignore any correlation with an absolute value less than 0.5.) Qualitatively, can you relate any of those correlations to your observations varying the sliders? For example, if the values for ω_{0} and c display a negative correlation, than increases in ω_{0} can be at least somewhat offset by decreasing c. Such a correlation would show up as the 1st row, 2nd column.