Skip to content

Commit 5dd006a

Browse files
committed
add full solar system problem and run
1 parent cbe66db commit 5dd006a

File tree

3 files changed

+179
-7
lines changed

3 files changed

+179
-7
lines changed

docs/source/projects/doc_solar_system.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ Full code: `pySDC/projects/Hamiltonian/solar_system.py <https://github.com/Paral
44

55
Results:
66

7+
.. literalinclude:: ../../../outer_solar_system_out.txt
8+
79
.. image:: ../../../data/outer_solar_system_hamiltonian.png
8-
:scale: 50 %
10+
:scale: 100 %
911
.. image:: ../../../data/outer_solar_system_positions.png
10-
:scale: 50 %
12+
:scale: 100 %
13+
14+
.. literalinclude:: ../../../full_solar_system_out.txt
15+
16+
.. image:: ../../../data/full_solar_system_hamiltonian.png
17+
:scale: 100 %
18+
.. image:: ../../../data/full_solar_system_positions.png
19+
:scale: 100 %
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
from __future__ import division
2+
3+
import numpy as np
4+
5+
from pySDC.implementations.problem_classes.OuterSolarSystem import outer_solar_system
6+
from pySDC.implementations.datatype_classes.particles import particles, acceleration
7+
from pySDC.core.Errors import ParameterError
8+
9+
10+
# noinspection PyUnusedLocal
11+
class full_solar_system(outer_solar_system):
12+
"""
13+
Example implementing the full solar system problem
14+
"""
15+
16+
def __init__(self, problem_params, dtype_u, dtype_f):
17+
"""
18+
Initialization routine
19+
20+
Args:
21+
problem_params (dict): custom parameters for the example
22+
dtype_u: particle data type (will be passed parent class)
23+
dtype_f: acceleration data type (will be passed parent class)
24+
"""
25+
26+
if 'sun_only' not in problem_params:
27+
problem_params['sun_only'] = False
28+
29+
# these parameters will be used later, so assert their existence
30+
essential_keys = []
31+
for key in essential_keys:
32+
if key not in problem_params:
33+
msg = 'need %s to instantiate problem, only got %s' % (key, str(problem_params.keys()))
34+
raise ParameterError(msg)
35+
36+
# invoke parant's class (!) super init, passing nparts, dtype_u and dtype_f
37+
super(outer_solar_system, self).__init__((3, 10), dtype_u, dtype_f, problem_params)
38+
39+
# gravitational constant
40+
self.G = 2.95912208286E-4
41+
42+
def u_exact(self, t):
43+
"""
44+
Routine to compute the exact/initial trajectory at time t
45+
46+
Args:
47+
t (float): current time
48+
Returns:
49+
dtype_u: exact/initial position and velocity
50+
"""
51+
assert t == 0.0, 'error, u_exact only works for the initial time t0=0'
52+
me = particles(self.init)
53+
54+
# initial positions and velocities taken from
55+
# https://www.aanda.org/articles/aa/full/2002/08/aa1405/aa1405.right.html
56+
me.pos.values[:, 0] = [0.0, 0.0, 0.0]
57+
me.pos.values[:, 1] = [-2.503321047836E-01, +1.873217481656E-01, +1.260230112145E-01]
58+
me.pos.values[:, 2] = [+1.747780055994E-02, -6.624210296743E-01, -2.991203277122E-01]
59+
me.pos.values[:, 3] = [-9.091916173950E-01, +3.592925969244E-01, +1.557729610506E-01]
60+
me.pos.values[:, 4] = [+1.203018828754E+00, +7.270712989688E-01, +3.009561427569E-01]
61+
me.pos.values[:, 5] = [+3.733076999471E+00, +3.052424824299E+00, +1.217426663570E+00]
62+
me.pos.values[:, 6] = [+6.164433062913E+00, +6.366775402981E+00, +2.364531109847E+00]
63+
me.pos.values[:, 7] = [+1.457964661868E+01, -1.236891078519E+01, -5.623617280033E+00]
64+
me.pos.values[:, 8] = [+1.695491139909E+01, -2.288713988623E+01, -9.789921035251E+00]
65+
me.pos.values[:, 9] = [-9.707098450131E+00, -2.804098175319E+01, -5.823808919246E+00]
66+
67+
me.vel.values[:, 0] = [0.0, 0.0, 0.0]
68+
me.vel.values[:, 1] = [-2.438808424736E-02, -1.850224608274E-02, -7.353811537540E-03]
69+
me.vel.values[:, 2] = [+2.008547034175E-02, +8.365454832702E-04, -8.947888514893E-04]
70+
me.vel.values[:, 3] = [-7.085843239142E-03, -1.455634327653E-02, -6.310912842359E-03]
71+
me.vel.values[:, 4] = [-7.124453943885E-03, +1.166307407692E-02, +5.542098698449E-03]
72+
me.vel.values[:, 5] = [-5.086540617947E-03, +5.493643783389E-03, +2.478685100749E-03]
73+
me.vel.values[:, 6] = [-4.426823593779E-03, +3.394060157503E-03, +1.592261423092E-03]
74+
me.vel.values[:, 7] = [+2.647505630327E-03, +2.487457379099E-03, +1.052000252243E-03]
75+
me.vel.values[:, 8] = [+2.568651772461E-03, +1.681832388267E-03, +6.245613982833E-04]
76+
me.vel.values[:, 9] = [+3.034112963576E-03, -1.111317562971E-03, -1.261841468083E-03]
77+
78+
# masses relative to the sun taken from
79+
# https://en.wikipedia.org/wiki/Planetary_mass#Values_from_the_DE405_ephemeris
80+
me.m[0] = 1.0 # Sun
81+
me.m[1] = 0.1660100 * 1E-06 # Mercury
82+
me.m[2] = 2.4478383 * 1E-06 # Venus
83+
me.m[3] = 3.0404326 * 1E-06 # Earth+Moon
84+
me.m[4] = 0.3227151 * 1E-06 # Mars
85+
me.m[5] = 954.79194 * 1E-06 # Jupiter
86+
me.m[6] = 285.88600 * 1E-06 # Saturn
87+
me.m[7] = 43.662440 * 1E-06 # Uranus
88+
me.m[8] = 51.513890 * 1E-06 # Neptune
89+
me.m[9] = 0.0073960 * 1E-06 # Pluto
90+
91+
return me

pySDC/projects/Hamiltonian/solar_system.py

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from pySDC.implementations.sweeper_classes.verlet import verlet
1313
from pySDC.implementations.datatype_classes.particles import particles, acceleration
1414
from pySDC.implementations.problem_classes.OuterSolarSystem import outer_solar_system
15+
from pySDC.implementations.problem_classes.FullSolarSystem import full_solar_system
1516
from pySDC.implementations.transfer_classes.TransferParticles_NoCoarse import particles_to_particles
1617

1718
from pySDC.helpers.stats_helper import filter_stats, sort_stats
@@ -67,6 +68,55 @@ def setup_outer_solar_system():
6768
return description, controller_params
6869

6970

71+
def setup_full_solar_system():
72+
"""
73+
Helper routine for setting up everything for the full solar system problem
74+
75+
Returns:
76+
description (dict): description of the controller
77+
controller_params (dict): controller parameters
78+
"""
79+
80+
# initialize level parameters
81+
level_params = dict()
82+
level_params['restol'] = 1E-10
83+
level_params['dt'] = 10.0
84+
85+
# initialize sweeper parameters
86+
sweeper_params = dict()
87+
sweeper_params['collocation_class'] = CollGaussLobatto
88+
sweeper_params['num_nodes'] = [5, 3]
89+
sweeper_params['spread'] = True
90+
91+
# initialize problem parameters for the Penning trap
92+
problem_params = dict()
93+
problem_params['sun_only'] = [False, True]
94+
95+
# initialize step parameters
96+
step_params = dict()
97+
step_params['maxiter'] = 50
98+
99+
# initialize controller parameters
100+
controller_params = dict()
101+
controller_params['hook_class'] = hamiltonian_output # specialized hook class for more statistics and output
102+
controller_params['logger_level'] = 30
103+
controller_params['predict'] = False
104+
105+
# Fill description dictionary for easy hierarchy creation
106+
description = dict()
107+
description['problem_class'] = full_solar_system
108+
description['problem_params'] = problem_params
109+
description['dtype_u'] = particles
110+
description['dtype_f'] = acceleration
111+
description['sweeper_class'] = verlet
112+
description['sweeper_params'] = sweeper_params
113+
description['level_params'] = level_params
114+
description['step_params'] = step_params
115+
description['space_transfer_class'] = particles_to_particles
116+
117+
return description, controller_params
118+
119+
70120
def run_simulation(prob=None):
71121
"""
72122
Routine to run the simulation of a second order problem
@@ -80,11 +130,24 @@ def run_simulation(prob=None):
80130
description, controller_params = setup_outer_solar_system()
81131
# set time parameters
82132
t0 = 0.0
83-
Tend = 20000.0
133+
Tend = 10000.0
84134
num_procs = 100
135+
maxmeaniter = 4.0
136+
elif prob == 'full_solar_system':
137+
description, controller_params = setup_full_solar_system()
138+
# set time parameters
139+
t0 = 0.0
140+
Tend = 1000.0
141+
num_procs = 100
142+
maxmeaniter = 16.0
85143
else:
86144
raise NotImplemented('Problem type not implemented, got %s' % prob)
87145

146+
f = open(prob + '_out.txt', 'w')
147+
out = 'Running ' + prob + ' problem with %s processors...' % num_procs
148+
f.write(out + '\n')
149+
print(out)
150+
88151
# instantiate the controller
89152
controller = allinclusive_classic_nonMPI(num_procs=num_procs, controller_params=controller_params,
90153
description=description)
@@ -103,22 +166,28 @@ def run_simulation(prob=None):
103166
iter_counts = sort_stats(filtered_stats, sortby='time')
104167

105168
# compute and print statistics
106-
for item in iter_counts:
107-
out = 'Number of iterations for time %4.2f: %2i' % item
108-
print(out)
169+
# for item in iter_counts:
170+
# out = 'Number of iterations for time %4.2f: %2i' % item
171+
# f.write(out)
172+
# print(out)
109173

110174
niters = np.array([item[1] for item in iter_counts])
111175
out = ' Mean number of iterations: %4.2f' % np.mean(niters)
176+
f.write(out + '\n')
112177
print(out)
113178
out = ' Range of values for number of iterations: %2i ' % np.ptp(niters)
179+
f.write(out + '\n')
114180
print(out)
115181
out = ' Position of max/min number of iterations: %2i -- %2i' % \
116182
(int(np.argmax(niters)), int(np.argmin(niters)))
183+
f.write(out + '\n')
117184
print(out)
118185
out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float(np.std(niters)), float(np.var(niters)))
186+
f.write(out + '\n')
119187
print(out)
188+
f.close()
120189

121-
assert np.mean(niters) <= 4.0, 'Mean number of iterations is too high, got %s' % np.mean(niters)
190+
assert np.mean(niters) <= maxmeaniter, 'Mean number of iterations is too high, got %s' % np.mean(niters)
122191

123192
fname = 'data/' + prob + '.dat'
124193
f = open(fname, 'wb')
@@ -213,6 +282,9 @@ def main():
213282
prob = 'outer_solar_system'
214283
run_simulation(prob)
215284
show_results(prob)
285+
prob = 'full_solar_system'
286+
run_simulation(prob)
287+
show_results(prob)
216288

217289

218290
if __name__ == "__main__":

0 commit comments

Comments
 (0)