1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: Create a mass-spring slinky!

  1. Apr 13, 2013 #1
    1. The problem statement, all variables and given/known data
    Create a Virtual Slinky with Python (or Excel)

    2. Relevant equations

    F= MA
    a whole bunch of other stuff (below)

    3. 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!


    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!
  2. jcsd
  3. Apr 13, 2013 #2


    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    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?
  4. Apr 15, 2013 #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.
  5. Apr 25, 2013 #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 in to 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.

    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.

    Attached Files:

  6. Apr 26, 2013 #5


    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    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 whereever 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.
  7. Apr 27, 2013 #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
  8. May 1, 2013 #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!
  9. May 1, 2013 #8


    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    No worries, glad you figured something out.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted