How can I Create a Virtual Slinky with Python or Excel?

  • Thread starter ultrapowerpie
  • Start date
  • Tags
    Slinky
In summary, the user inputs the number of mass blocks, the k-value of the springs, the length of the springs, and the desired length of the simulation. The program then calculates the mass forces on each block, calculates the new velocities, and updates the positions of the blocks.
  • #1
ultrapowerpie
58
0

Homework Statement


Create a Virtual Slinky with Python (or Excel)


Homework Equations



F=-k*deltaT
F= MA
a whole bunch of other stuff (below)


The Attempt at a Solution



So, essentially, for a "grandiose math modeling/applied physics project I need to complete a seminar course, I have been tasked with making a pseudo-slinky with a mass-spring system instead!


http://ars.els-cdn.com/content/image/1-s2.0-S0045794910002968-gr1.jpg

See A? That's essentially what it's supposed to be like, except the wall points are just more masses instead.

To keep things simple, all masses are uniform and we're only concerned with 2D motion (x and y dirction)

SO, I need help essentially constructing said virtual psuedo-slink. Technically I only need for output the magical S (position) function, which essentially is S(x,y,t,N), where x and y are coordinate positions, t is time and N is the mass block (N1, N2, too Nk).

So the program is essentially a bunch of recursive functions that simulate the movement of the mass blocks based on an external force applied to the system (one push/pull)


So, essentially, to start out the program will ask the following user input:

Number of Mass Blocks:
K-value of springs:
Length of Spring:
How long do you want the simulation to run (Max T value):
(Number of springs is Number of Blocks-1)


For output would be the position of the blocks, but if it could actually visually display the stuff that'd be fantastic.

Now one problem is that I'm a newbie when it comes to Python, but this is the Physics Help forum, so I've come here asking for help/guidance on generating said slinky with recurssive programs/loops and whanot. IE, what formula to use, what to reference where, etc.

And if anyone actually knows Python that's a bonus but I'm mainly here to get the actual math/physics of it right before I even begin trying to play with a new language/excel spreadsheets.

So thanks for any help!
 
Physics news on Phys.org
  • #2
It sounds like fun!

I think what you can do is something like the following:

if you draw a free body diagram for any mass (except the two ends ones) you see that it has two horizontal forces acting on it, namely the restoring forces from the springs on either side of it. These spring forces, in turn, depend on how much each spring is stretched or compressed from its equilibrium length. The amount of stretch or compression, in turn, depends on the distance between the two masses that are at either end of that spring.

So, you're going to have a loop that does the following things every timestep:

First, you can update all of the dynamical variables. So, update the velocity of each mass using the acceleration from the previous timestep, and the time interval between timesteps. Update the position in the same way using the velocity from the previous timestep.

Next you can compute the magnitudes and directions of the restoring forces in every spring based on the relative positions of the masses at that timestep. Using these restoring forces, find the net force on each mass, and hence the new acceleration it experiences (which will be applied in the next timestep to update the velocity and hence the position).

I can help you with python specifics once you get to the point of actually trying to write some code. Does that make sense so far?
 
  • #3
Wow, that's fantastic that someone like you is interested in helping me. :D

I do get what you're saying, right now I'm caught up in another class but later this week (Wednesdayish) I'll be able to devote more time to this project and be able to respond with my results based on your post. I just wanted to let you know that I wasn't dead or anything and still needed help.
 
  • #4
Alright, so let me try to reconstruct this with the flowing diagram (see attached)


So, for the example, we’re keeping it simple: two boxes, 1 spring like you said. Then this will hopefully get us enough to set up a large recursive function later on.


Ok, so right now we’re sticking with strictly longitudinal waves then, yes? Since you only mentioned the horizontal axis. Ultimately I need it to be able to model Transverse wave as well but focusing on the X direction first would most likely make things a heck of a lot easier.

Also we’re assuming the springs are massless to help simplify things as well. And as stated before, all masses/springs are uniform. For now at least. I’m also adding that I know nothing of Tensors and I really hope we can just use Hooke’s Law to accomplish everything. But on to the actual program outline.


So as stated before, there’s a few equations that are necessary:

F = MA

Spring Force = -k*delta T


And the definitions of displacement, velocity and acceleration and how they relate to each other.
So let’s set up a scenario for the above diagram and see if that can be formed into a recursive loop. First, global variables:

Starting Force (F0): This comes from the left side and is always defined by the user. For now it can only be + for right (compressing the spring)

K= Spring Constant is also defined by user

Max Length of Spring (Xmax): A spring can only be stretched so far, so Delta X needs some sort of limit to constrain it, otherwise the spring won’t act like a spring.

Min Length of Spring(Xmin): A spring can only be compressed so far, and thus needs a limit there as well

Length of spring at rest(X0): That way delta X can be calculated, also will be used to determine the initial positions of the boxes since they will all be one spring length apart from each other.

m= Mass is also defined by the user, for boxes

Total Time (T): Obvious, the program only runs as long as needed

Time interval (ΔT): The user needs to define delta T for the program to accurately calculate movement. I recommend something like .1 but that’s details.

Next are the Dynamic Variables, which change after each time step, and is by far the trickier of the things to set up, but let me give it a shot:

Xq = The X coordinate of the box. For the sake of ease, the boxes/masses will be point masses on the springs to simplify calculations. If needed the program could possibly be expanded to include a mass of actual volume but for now we’re assuming the masses will not affect distance. Q is used to denote the number of the box (from the left), so for this outline only q2 and q3 exist. These will be used to help distinguish the different variables used in the dynamics.



Vq= Similar to the X position, we need the velocity the box is moving into get to the position. Since we are only dealing with longitudinal the velocity is only in the x direction, but can be re-defined later to include x/y

Aq= The Acceleration of each block


Fq= The net force on each block

ΔXk = The compression/stretch of the associated spring.

Now that all that is out of the way, I’ll do three time intervals to show how the loop should flow.

@T = 0
Let Xq2= .5 m and Xq3= 1.0 m, with the spring length, K0 = .5 m. The system is at equilibrium just as the Force, we’ll say 5 Newtons is pushed onto the system. Each block is .5 Kg and K = .75


@T= .1
F0 is applied to q2, thus the program first needs to calculate Aq2 = F0/M, which is 5/.5 = 10 m/s^2

To get the velocity we merely multiply the acceleration by the amount of time, so Vq2 = 10*.1 = 1 m/s

Finally to get the new position we multiply the velocity by time, so Xq2= 1*.1= .1 meters + the original Xq2 = .6m (I know that you can easily do that in C++, pretty sure Python can do that as well hence the set up)

Before the next step the program would need ΔXk, so the actual programming would look like this:
ΔXk = 1*.1 = .1 meters,

Xq2= ΔXk + Xq2

Also, before the loop carries on, an if/then statement will be needed to check if the spring has reached it’s maximum limits, in which case the program will automatically put the Max/Min of the spring for delta X.

Now that the program has analyzed the first block, it now calculates the force K3 is pushing onto q3. Note that I’m not calculating the restoring force but the actual force that pushes on the spring since we want to know how much the spring pushes against another block, so I’m taking out the – sign that is conventionally used. Let me know if that’s wrong.

Fk= k* ΔXk which equals this when variables are substituted: Fk = .75 *.1 = .075 Newtons.
Now the program repeats the process listed above for calculating q3’s X, V and A and saving them.

@T=.2
Here’s where things get a little fuzzy for me since we’re currently treating the left side as a black box, so we’re just going to label it Fc until we can get that straightened out.

So Fc is recalculated and the program goes through everything again for q2, so Aq2 = Fc/.5, etc. etc.


There is one thing that should be noted that will appear in the code from the second time interval forward: The if/then loop established if the spring hits the compression/tension maximum length.

Once the spring has hit this point it will start to act in the reverse direction since the spring literally can’t extend any further and we’re assuming that springs can’t break. Unless we want to program it to give an error that says “too much force applied”.
But essentially, the new force of the spring becomes F=-k*delta X, thus allowing the spring to go backwards. I’m not quite sure if that’s right so help is appreciated.

But that’s the gist of it. I hope this is right and I explained my thought process clearly. Please point out any flaws in this line of logic and what the next step is (probably figuring in the first block most likely if it somehow doesn't follow the above pattern)

I would assume that for the Y direction we would simply apply the same program but only in terms of Y, where the initial Force is given an angle (with respect to the horizontal direction) so that the program can split the initial force into X and Y components and then go to town.
 

Attachments

  • Box-spring.jpg
    Box-spring.jpg
    4.8 KB · Views: 425
  • #5
I think what you have there is mostly right. It's a lot to slog though. Here's how I would approach the first few timesteps, and you can compare that to what you have. I'm just going to call my masses m1 (left) and m2 (right), their positions x1, x2, etc. The spring constant is k. The initial force on m1 is F0, pointing to the right.

First you need to set up some initial conditions.

At t = 0, it is true that:

x1 = 0 m (I figured I can put the origin of my coordinate system wherever I want, so why not at the location of the left mass?)

x2 = +0.5 m

I'm going to set up my coord system so that the positive x direction is to the right.

We'll say that the equilibrium length of the spring is ##\ell_0##= 0.5 m. So, it follows that the displacement of the spring (the thing that determines the restoring force) is ##\Delta \ell = \ell - \ell_0##, where the spring length ##\ell## = x2 - x1, always. Maybe I'm overcomplicating the notation, but I find it helpful to distinguish x positions of the masses from spring lengths, which are differences between x positions. So in this case, x2 - x1 = 0.5 m, therefore ##\ell = \ell_0## and the spring force is 0 N. Getting back to the initial conditions, it's also true that:

v1 = v2 = 0 m/s

a2 = 0 m/s2

a1 = F0/m1

You have to decide how long F0 is applied for. I'm going to assume it's only on for the first time step, and turns off after that. So that's the situation for t = t0 = 0.

At t = t1 = Δt:

update the positions using the velocities (I'll use square brackets to indicate what timestep we're at)

x2[1] = x2[0] + v2[0]*Δt

= 0.5 m + 0 m = 0.5 m

x1[1] = x1[0] + v1[0]*Δt = 0 m + 0 m = 0 m

So, since the initial velocities were 0 (and these apply throughout the first time interval), nothing has moved after one timestep.

update the velocities using the accelerations:

v2[1] = v2[0] + a2[0] * Δt = 0 m/s + 0 m/s

v1[1] = v1[0] + a1[0] * Δt = 0 m/s + (F0/m1)Δt m/s

So, after one timestep, the left mass has gained some speed as determined by its initial acceleration.

Now, compute the new accelerations, that will apply during the next timestep. Since the applied force F0 is now gone, only the spring restoring force remains. So, compute the force on each mass due to the spring. You have to get the signs right. If ##\Delta \ell < 0##, the spring is compressed, and therefore the force on the left mass points towards the left (away from the centre) and the force on the right mass points towards the right (away from the centre). If ##\Delta \ell > 0##, the spring is stretched, and the opposite is true: the force on the left mass is to the right (towards the centre) and the force on the right mass is to the left (towards the centre). This means that F1 is consistently equal to k##\Delta \ell##, and F2 is consistently -k##\Delta \ell## using our sign convention. Just keep that in mind.

F1[1] = k(##\ell##[1] - ##\ell_0##) = k( (x2[1] - x1[1]) - ##\ell_0##) = k(0.5 m - 0.5 m) = 0 N
F2[1] = 0 N as well, because the spring is still unstretched and uncompressed.

Therefore a1[1] = a2[1] = 0 m/s2

At t = t2 = 2*Δt:

update the positions using the velocities (I'll use square brackets to indicate what timestep we're at)

x2[2] = x2[1] + v2[1]*Δt

= 0.5 m + 0 m = 0.5 m

x1[2] = x1[1] + v1[1]*Δt = 0 m + (F0/m1)Δt*Δt m/s (whatever that is)

so now, x1 has moved a bit to the right, on account of its velocity in the previous timestep

update the velocities using the accelerations:

v2[2] = v2[1] + a2[1] * Δt = 0 m/s + 0 m/s

v1[2] = v1[1] + a1[1] * Δt = (F0/m1)Δt m/s + 0 m/s

So, since there was still no acceleration in the last time interval, the left mass keeps moving to the right at the same speed.

Now compute the new value of the spring force:

F1[2] = k(##\ell##[2] - ##\ell_0##) = k( (x2[2] - x1[2]) - ##\ell_0##)

Now, since x1[2] is no longer 0 m, but slightly to the right of this, it follows that the spring length x2[2] - x1[2] is slightly less than 0.5 m. So the spring is compressed, and some force acts on m1 to the left.

Similarly, some force acts on m2 to the right.

So, the accelerations a2[2] and a1[2] that we'd compute for use in the next timestep would be non-zero, and interesting stuff will finally start to happen.
 
  • #6
Yeah we basically have the same algorithim down for how this all works, and I actually had to manually compute a Projectile Launch before with drag factored in, so I'm at least familiar with changing accelerations, so we're pretty much in line there.

So, here's where I'd get stuck:

1) How does a spring behave, Y wise? Can we just apply hooke's law for the y direction and everything will be ok? Since the model needs to simulate transverse in addition to longitudinal. If that's the case then that computation is also the same. If it's NOT, then I do not know how to model the y direction.

2) This looks easily applicable to multi masses that the user defines and I would just need some help on how to use Python to set up loops. I know the bare bone basics of the language and that's about it. Ultimately I'd like to somehow get a visual repersentation of everything but my teacher said that just the list of each mass at n time interval in table format would suffice.

3) After an actual model is assembled, I might be tempted to play with the input commands to allow the user to apply a sustained force, like for example an alternating force to extend a transverse wave, since one push would only send it so far. I'm just asking if this part is doableish without going too code happy

4) Thanks again for mentoring through this, it's nice to have someone to help make sure that I'm not going off on random tangents and staying focused on the correct physics to apply
 
  • #7
Nevermind, I got it done in Excel instead. Made it a bit ugly with the referencing and whatnot but I got it to work. Thanks for the physics help though!
 
  • #8
ultrapowerpie said:
Nevermind, I got it done in Excel instead. Made it a bit ugly with the referencing and whatnot but I got it to work. Thanks for the physics help though!

No worries, glad you figured something out.
 

FAQ: How can I Create a Virtual Slinky with Python or Excel?

What is a mass-spring slinky?

A mass-spring slinky is a physical system that consists of a long, coiled spring with a mass attached to one end. It is often used as a model to demonstrate oscillatory motion and wave behavior.

How do you create a mass-spring slinky?

To create a mass-spring slinky, you will need a long, coiled spring, a mass (such as a weight or ball), and a support system (such as a stand or clamp). Attach one end of the spring to a fixed point, then attach the mass to the other end. The spring should be able to stretch and compress without any obstructions.

What factors affect the motion of a mass-spring slinky?

The motion of a mass-spring slinky is affected by several factors, including the mass of the attached weight, the length and stiffness of the spring, and the force applied to the spring. The surface on which the slinky is placed can also affect its motion.

How does a mass-spring slinky demonstrate wave behavior?

A mass-spring slinky demonstrates wave behavior by exhibiting properties such as amplitude, frequency, and wavelength. When the weight attached to the slinky is moved up and down, it creates a wave that travels along the length of the spring. This wave can be reflected, refracted, and interfere with other waves, just like real waves in nature.

What can a mass-spring slinky be used for in scientific research?

Mass-spring slinkies are often used in scientific research as a simple model to study wave behavior and oscillatory motion. They can also be used to demonstrate concepts such as resonance, damping, and energy transfer. In addition, mass-spring slinkies are commonly used in educational settings to teach students about physics and engineering principles.

Similar threads

Back
Top