Skip to content

Commit b0e228c

Browse files
committed
bugfix, better coarsening, readme
1 parent b732dbc commit b0e228c

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

pySDC/implementations/problem_classes/OuterSolarSystem.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
# noinspection PyUnusedLocal
1111
class outer_solar_system(ptype):
1212
"""
13-
Example implementing the harmonic oscillator
13+
Example implementing the outer solar system problem
1414
"""
1515

1616
def __init__(self, problem_params, dtype_u, dtype_f):
@@ -23,6 +23,9 @@ def __init__(self, problem_params, dtype_u, dtype_f):
2323
dtype_f: acceleration data type (will be passed parent class)
2424
"""
2525

26+
if 'sun_only' not in problem_params:
27+
problem_params['sun_only'] = False
28+
2629
# these parameters will be used later, so assert their existence
2730
essential_keys = []
2831
for key in essential_keys:
@@ -32,6 +35,8 @@ def __init__(self, problem_params, dtype_u, dtype_f):
3235

3336
# invoke super init, passing nparts, dtype_u and dtype_f
3437
super(outer_solar_system, self).__init__((3, 6), dtype_u, dtype_f, problem_params)
38+
39+
# gravitational constant
3540
self.G = 2.95912208286E-4
3641

3742
def eval_f(self, u, t):
@@ -46,24 +51,37 @@ def eval_f(self, u, t):
4651
"""
4752
me = acceleration(self.init, val=0.0)
4853

49-
for i in range(self.init[-1]):
50-
for j in range(i):
51-
dx = u.pos.values[:, i] - u.pos.values[:, j]
54+
# compute the acceleration due to gravitational forces
55+
# ... only with respect to the sun
56+
if self.params.sun_only:
57+
58+
for i in range(1, self.init[-1]):
59+
dx = u.pos.values[:, i] - u.pos.values[:, 0]
5260
r = np.sqrt(np.dot(dx, dx))
5361
df = self.G * dx / (r ** 3)
54-
me.values[:, i] -= u.m[j] * df
55-
me.values[:, j] += u.m[i] * df
62+
me.values[:, i] -= u.m[0] * df
63+
64+
# ... or with all planets involved
65+
else:
66+
67+
for i in range(self.init[-1]):
68+
for j in range(i):
69+
dx = u.pos.values[:, i] - u.pos.values[:, j]
70+
r = np.sqrt(np.dot(dx, dx))
71+
df = self.G * dx / (r ** 3)
72+
me.values[:, i] -= u.m[j] * df
73+
me.values[:, j] += u.m[i] * df
5674

5775
return me
5876

5977
def u_exact(self, t):
6078
"""
61-
Routine to compute the exact trajectory at time t
79+
Routine to compute the exact/initial trajectory at time t
6280
6381
Args:
6482
t (float): current time
6583
Returns:
66-
dtype_u: exact position and velocity
84+
dtype_u: exact/initial position and velocity
6785
"""
6886
assert t == 0.0, 'error, u_exact only works for the initial time t0=0'
6987
me = particles(self.init)
@@ -82,12 +100,12 @@ def u_exact(self, t):
82100
me.vel.values[:, 4] = [0.00288930, 0.00114527, 0.00039677]
83101
me.vel.values[:, 5] = [0.00276725, -0.0017072, -0.00136504]
84102

85-
me.m[0] = 1.00000597682
86-
me.m[1] = 0.000954786104043
87-
me.m[2] = 0.000285583733151
88-
me.m[3] = 0.0000437273164546
89-
me.m[4] = 0.0000517759138449
90-
me.m[5] = 1.0 / 130000000.0
103+
me.m[0] = 1.00000597682 # Sun
104+
me.m[1] = 0.000954786104043 # Jupiter
105+
me.m[2] = 0.000285583733151 # Saturn
106+
me.m[3] = 0.0000437273164546 # Uranus
107+
me.m[4] = 0.0000517759138449 # Neptune
108+
me.m[5] = 1.0 / 130000000.0 # Pluto
91109

92110
return me
93111

pySDC/projects/Hamiltonian/README.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Simple problems
99

1010
We first test the integrator for some rather simple problems, namely the harmonic oscillator and the Henon-Heiles problem.
1111
For both problems we make use of the hook ``hamiltonian_output`` to monitor the deviation from the exact Hamiltonian.
12+
PFASST is run with 100 processors (virtually parallel) and the deviation from the initial Hamiltonian is shown.
1213

1314
.. include:: doc_hamiltonian_simple.rst
1415

@@ -17,7 +18,8 @@ Solar system problem
1718

1819
In this slightly more complex setup we simulate the movement of planets in the outer solar system.
1920
For this, only six planets are modeled, namely the Sun (which in its mass contains the inner planets), Jupiter, Saturn, Uranus, Neptune and Pluto.
20-
The gravitational forces are computed using a simple N^2 solver.
21+
The acceleration due to gravitational forces are computed using a simple N^2 solver.
2122
All this is implemented within the ``OuterSolarSystem`` problem class.
23+
Coarsening can be done using only the sun for computing the acceleration.
2224

2325
.. include:: doc_solar_system.rst

pySDC/projects/Hamiltonian/hamiltonian_output.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def post_iteration(self, step, level_number):
2727
step (pySDC.Step.step): the current step
2828
level_number (int): the current level number
2929
"""
30-
super(hamiltonian_output, self).post_step(step, level_number)
30+
super(hamiltonian_output, self).post_iteration(step, level_number)
3131

3232
# some abbreviations
3333
L = step.levels[0]

pySDC/projects/Hamiltonian/solar_system.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from collections import defaultdict
33
import os
44
import dill
5+
import numpy as np
56

67
import pySDC.helpers.plot_helper as plt_helper
78

@@ -12,7 +13,7 @@
1213
from pySDC.implementations.problem_classes.OuterSolarSystem import outer_solar_system
1314
from pySDC.implementations.transfer_classes.TransferParticles_NoCoarse import particles_to_particles
1415

15-
from pySDC.helpers.stats_helper import filter_stats
16+
from pySDC.helpers.stats_helper import filter_stats, sort_stats
1617
from pySDC.projects.Hamiltonian.hamiltonian_output import hamiltonian_output
1718

1819

@@ -38,6 +39,7 @@ def setup_outer_solar_system():
3839

3940
# initialize problem parameters for the Penning trap
4041
problem_params = dict()
42+
problem_params['sun_only'] = [False, True]
4143

4244
# initialize step parameters
4345
step_params = dict()
@@ -93,6 +95,30 @@ def run_simulation(prob=None):
9395
# call main function to get things done...
9496
uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
9597

98+
# filter statistics by type (number of iterations)
99+
filtered_stats = filter_stats(stats, type='niter')
100+
101+
# convert filtered statistics to list of iterations count, sorted by process
102+
iter_counts = sort_stats(filtered_stats, sortby='time')
103+
104+
# compute and print statistics
105+
for item in iter_counts:
106+
out = 'Number of iterations for time %4.2f: %2i' % item
107+
print(out)
108+
109+
niters = np.array([item[1] for item in iter_counts])
110+
out = ' Mean number of iterations: %4.2f' % np.mean(niters)
111+
print(out)
112+
out = ' Range of values for number of iterations: %2i ' % np.ptp(niters)
113+
print(out)
114+
out = ' Position of max/min number of iterations: %2i -- %2i' % \
115+
(int(np.argmax(niters)), int(np.argmin(niters)))
116+
print(out)
117+
out = ' Std and var for number of iterations: %4.2f -- %4.2f' % (float(np.std(niters)), float(np.var(niters)))
118+
print(out)
119+
120+
assert np.mean(niters) <= 4.0, 'Mean number of iterations is too high, got %s' % np.mean(niters)
121+
96122
fname = 'data/' + prob + '.dat'
97123
f = open(fname, 'wb')
98124
dill.dump(stats, f)
@@ -118,7 +144,6 @@ def show_results(prob=None, cwd=''):
118144
for k, v in extract_stats.items():
119145
result[k.iter].append((k.time, v))
120146
for k, v in result.items():
121-
assert k <= 4, 'Number of iterations is too high for %s, got %s' % (prob, k)
122147
result[k] = sorted(result[k], key=lambda x: x[0])
123148

124149
plt_helper.mpl.style.use('classic')

0 commit comments

Comments
 (0)