Posts: 14
Threads: 4
Joined: Apr 2017
(Jun-14-2017, 05:29 AM)Skaperen Wrote: yes, you could do it with separate lists, where a common list index is your system body identification. if you already know Fortran (still in common use in physics) then you probably see that as the classic way there.
too bad you don't have the time to do it right. but then, if you did do it right they might not understand it.
Yeah this is for a computational physics class, and it's my first experience with any type of programming. I plan on using python for more than just physics though, so I'll definitely have to learn the right way.
Posts: 8,160
Threads: 160
Joined: Sep 2016
sure, you can stick to your original setup. However in any case I would add second nested loop for calculating the gravity effect, instead of defining variable for each planet
Posts: 14
Threads: 4
Joined: Apr 2017
What would using a nested loop do here? Maybe I'm missing something obvious, but won't it still need an individual calculation for each planet?
Posts: 8,160
Threads: 160
Joined: Sep 2016
Jun-14-2017, 08:23 AM
(This post was last modified: Jun-14-2017, 08:24 AM by buran.)
looking at this part of your code
while True:
for i in arange(0,9,1):
rate(1000000)
t=t+dt
rsun = posit[0]-posit[i]
if mag(rsun) == 0:
continue
Fsun = ((G*mass[0]*mass[i])/(mag(rsun)**2))* norm(rsun) #Calculating the force of gravity from the sun
rmerc = posit[1]-posit[i]
if mag(rmerc)==0:
continue
Fmerc = ((G*mass[1]*mass[i])/(mag(rmerc)**2))* norm(rmerc)
rven = posit[2]-posit[i]
if mag(rven)==0:
continue
Fven = ((G*mass[2]*mass[i])/(mag(rven)**2))* norm(rven)
rear = posit[3]-posit[i]
if mag(rear)==0:
continue
Fear = ((G*mass[3]*mass[i])/(mag(rear)**2))* norm(rear)
rmars = posit[4]-posit[i]
if mag(rmars)==0:
continue
Fmars = ((G*mass[4]*mass[i])/(mag(rmars)**2))* norm(rmars)
rjup = posit[5]-posit[i]
if mag(rjup)==0:
continue
Fjup = ((G*mass[5]*mass[i])/(mag(rjup)**2))* norm(rjup)
rsat = posit[6]-posit[i]
if mag(rsat)==0:
continue
Fsat = ((G*mass[6]*mass[i])/(mag(rsat)**2))* norm(rsat)
ruran = posit[7]-posit[i]
if mag(ruran)==0:
continue
Furan = ((G*mass[7]*mass[i])/(mag(ruran)**2))* norm(ruran)
rnep = posit[8]-posit[i]
if mag(rnep)==0:
continue
Fnep = ((G*mass[8]*mass[i])/(mag(rnep)**2))* norm(rnep)
Fnet = Fsun + Fmerc + Fven + Fear + Fmars + Fjup + Fsat + Furan + Fnep
acc[i]=Fnet/mass[i]
vel[i]=vel[i] + acc[i]*dt
posit[i]=posit[i] + vel[i]*dt Not 100% sure, but it looks like it will never calculate anything - you loop over all objects so at least one mag will be 0, so it will continue with next i, without even reaching Fnet = Fsun + Fmerc + Fven + Fear + Fmars + Fjup + Fsat + Furan + Fnep and next lines. Not to mention repeating code
I think what you want is
while True:
for i in arange(0,9,1):
Fnet = 0
for j in range(i+1,9,1):
rate(1000000)
t=t+dt
r = posit[j]-posit[i]
F = ((G*mass[j]*mass[i])/(mag(r)**2))* norm(r) #Calculating the force of gravity from object j over object i
Fnet += F
acc[i]=Fnet/mass[i]
vel[i]=vel[i] + acc[i]*dt
posit[i]=posit[i] + vel[i]*dt
sun.pos=posit[0]
mercury.pos=posit[1]
venus.pos=posit[2]
earth.pos=posit[3]
mars.pos=posit[4]
jupiter.pos=posit[5]
saturn.pos=posit[6]
uranus.pos=posit[7]
neptune.pos=posit[8]
this way, when i=0, j will take values from 1 to 8
when i=1, j will take values from 2 to 8, etc.
PS. Not sure where the best place for rate(1000000) is...
Posts: 8,160
Threads: 160
Joined: Sep 2016
and in the setup with single list
from visual import * # I HATE this
myuniv = display(range=vector(7*10**12,7*10**12,7*10**12))
G = 6.674*10**-11 #Gravitational constant
# define objects
cosmic_objects = (('sun', {'r':9.9*10**10, 'mass':1.989*10**30, 'pos':vector(0,0,0), 'vel':vector(0,0,0), 'acc':vector(0,0,0), 'color':color.yellow}),
('mercury', {'r':2.44*10**6, 'mass':3.285*10**23,'pos':vector(5.791*10**10,0,0), 'vel': vector(0,4.87*10**4,0), 'acc':vector(0,0,0), 'color':color.red}),
('venus', {'r':6.052*10**6, 'mass':4.867*10**24, 'pos':vector(1.082*10**11,0,0), 'vel':vector(0,3.502*10**4,0), 'acc':vector(0,0,0), 'color':color.yellow}), # I added color here
('earth', {'r':6.371*10**6, 'mass':5.972*10**24, 'pos':vector(1.496*10**11,0,0), 'vel':vector(0,2.98*10**4,0), 'acc':vector(0,0,0), 'color':color.green}),
('mars', {'r':3.39*10**6, 'mass':6.39*10**23, 'pos':vector(2.279*10**11,0,0), 'vel':vector(0,2.401*10**4,0), 'acc':vector(0,0,0), 'color':color.red}),
('jupiter', {'r':6.99*10**7, 'mass':1.898*10**27, 'pos':vector(7.785*10**11,0,0), 'vel':vector(0,1.307*10**4,0), 'acc':vector(0,0,0), 'color':color.blue}),
('saturn', {'r':5.823*10**7, 'mass':5.68*10**26, 'pos':vector(1.429*10**12,0,0), 'vel':vector(0,9.69*10**3,0), 'acc':vector(0,0,0), 'color':color.yellow}),
('uranus', {'r':2.536*10**7, 'mass':8.68*10**25, 'pos':vector(2.871*10**12,0,0), 'vel':vector(0,6.81*10**3,0), 'acc':vector(0,0,0), 'color':color.cyan}),
('neptune', {'r':2.462*10**7, 'mass':1.024*10**26, 'pos':vector(4.498*10**12,0,00), 'vel':vector(0,5.43*10**3,0), 'acc':vector(0,0,0), 'color':color.blue})) # I added color here
objects_sorted_by_mass = sorted(cosmic_objects, key=lambda x:x[1]['mass'], reverse=True) # all objects, sorted by mass descending
#visualize objects
solar_system = {}
for name, obj in cosmic_objects:
solar_system[name] = sphere(pos=obj['pos'], radius=obj['r'], color=obj['color'], make_trail=True)
t = 0.0
dt = 150000
while True:
for i, obj_name, obj in enumerate(objects_sorted_by_mass): # loop over all objects, sorted by mass descending
Fnet = 0
for obj_name2, obj2 in objects_sorted_by_mass[:i]:
rate(1000000)
t=t+dt
r = obj2['pos'] - obj['pos'] # distance between obj2 and obj
Fnet += ((G*obj2['mass']*obj['mass'])/(mag(r)**2))* norm(r) #Calculating the force of gravity from obj2 to the obj
obj['acc'] = Fnet/obj['mass']
obj['vel'] += obj['acc']*dt
obj['pos'] += obj['vel']*dt
solar_system[obj_name].pos = obj['pos']
Posts: 14
Threads: 4
Joined: Apr 2017
(Jun-14-2017, 08:23 AM)buran Wrote: this way, when i=0, j will take values from 1 to 8
when i=1, j will take values from 2 to 8, etc.
Okay that makes a lot of sense. I just changed Fnet to a vector.
while True:
for i in arange(0,9,1):
Fnet = vector(0,0,0)
for j in range(i+1,9,1):
rate(1000000)
t=t+dt
r = posit[j]-posit[i]
F = ((G*mass[j]*mass[i])/(mag(r)**2))* norm(r) #Calculating the force of gravity from object j over object i
Fnet += F
acc[i]=Fnet/mass[i]
vel[i]=vel[i] + acc[i]*dt
posit[i]=posit[i] + vel[i]*dt
sun.pos=posit[0]
mercury.pos=posit[1]
venus.pos=posit[2]
earth.pos=posit[3]
mars.pos=posit[4]
jupiter.pos=posit[5]
saturn.pos=posit[6]
uranus.pos=posit[7]
neptune.pos=posit[8] No more errors, but for some reason the planets just go in a straight line. They're accelerating like there's some kind of force on them , but only in one direction...is this because when i = 0 , j = 1 every time? That would mean only mercury is effected by the suns gravity, and only venus is effected by mercuries gravity and so on.
Posts: 8,160
Threads: 160
Joined: Sep 2016
Jun-14-2017, 10:36 AM
(This post was last modified: Jun-14-2017, 10:36 AM by buran.)
(Jun-14-2017, 10:03 AM)JakeWitten Wrote: is this because when i = 0 , j = 1 every time? no, that is not correct
for i in range (0,9,1):
for j in range(i+1,9,1):
print 'i:{}, j:{}'.format(i,j) Output: i:0, j:1
i:0, j:2
i:0, j:3
i:0, j:4
i:0, j:5
i:0, j:6
i:0, j:7
i:0, j:8
i:1, j:2
i:1, j:3
i:1, j:4
i:1, j:5
i:1, j:6
i:1, j:7
i:1, j:8
i:2, j:3
i:2, j:4
i:2, j:5
i:2, j:6
i:2, j:7
i:2, j:8
i:3, j:4
i:3, j:5
i:3, j:6
i:3, j:7
i:3, j:8
i:4, j:5
i:4, j:6
i:4, j:7
i:4, j:8
i:5, j:6
i:5, j:7
i:5, j:8
i:6, j:7
i:6, j:8
i:7, j:8
I think that is what you meant by "For example, when calculating mercury, 'i' needs to be in the range 1-9, rather than 0-9. For venus it needs to be 2-9. Otherwise the forces end up canceling out and the planets don't move."
Posts: 8,160
Threads: 160
Joined: Sep 2016
Is my understanding correct that the F force calculated for each pair, e.g. i=0, j=1 is net, i.e. no need to calculate also for i=1, j=0?
Posts: 14
Threads: 4
Joined: Apr 2017
(Jun-14-2017, 10:40 AM)buran Wrote: Is my understanding correct that the F force calculated for each pair, e.g. i=0, j=1 is net, i.e. no need to calculate also for i=1, j=0? Yes, its net.
It didn't occur to me that the nested loop would cycle through the full range of j for every i value, so that's not the problem...
I still don't know what the issue is then. It kind of looks like the force from the sun isn't being accounted for, but I don't see why it wouldn't be.
Posts: 8,160
Threads: 160
Joined: Sep 2016
(Jun-14-2017, 10:58 AM)JakeWitten Wrote: It kind of looks like the force from the sun isn't being accounted for, but I don't see why it wouldn't be. I think it is accounted for when i=0 and j is 1 to 8...
Of course I'm not an expert in the field :-)
|