Skip to content

Commit 3254981

Browse files
committed
TL: local update
1 parent 5193238 commit 3254981

File tree

3 files changed

+95
-33
lines changed

3 files changed

+95
-33
lines changed

pySDC/playgrounds/dedalus/demos/demo_timestepper_advection.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
# -----------------------------------------------------------------------------
1616
# User parameters
1717
# -----------------------------------------------------------------------------
18-
listK = [0, 1, 2] # list of initial wavenumber in the solution (amplitude 1)
19-
nX = 128 # number of points in x (periodic domain)
18+
listK = range(32) # list of initial wavenumber in the solution (amplitude 1)
19+
nX = 64 # number of points in x (periodic domain)
2020

2121
# -----------------------------------------------------------------------------
2222
# Solver setup
@@ -32,9 +32,10 @@
3232
'RK443': 3,
3333
'ERK4': 4}
3434

35+
implSweep = 'MIN-SR-FLEX'
3536
SpectralDeferredCorrectionIMEX.setParameters(
3637
nNodes=4, nodeType='LEGENDRE', quadType='RADAU-RIGHT',
37-
implSweep='MIN-SR-FLEX', explSweep='PIC', initSweep='COPY')
38+
implSweep=implSweep, explSweep='PIC', initSweep='COPY')
3839

3940
# -----------------------------------------------------------------------------
4041
# Simulations
@@ -52,7 +53,7 @@
5253
timeStepper.setParameters(nSweeps=nSweeps)
5354
useSDC = True
5455

55-
scheme = f"SDC[{SpectralDeferredCorrectionIMEX.implSweep}, K={nSweeps}]"
56+
scheme = f"SDC[{implSweep}, K={nSweeps}]"
5657
else:
5758
scheme = timeStepper.__name__
5859
print(f" -- solving using {scheme}")
@@ -74,7 +75,7 @@ def getErr(nStep):
7475
return dt, err
7576

7677
# Run all simulations
77-
listNumStep = [2**(i+2) for i in range(11)]
78+
listNumStep = [2**(i+3) for i in range(11)]
7879
dt, err = np.array([getErr(n) for n in listNumStep]).T
7980

8081
# Plot error VS time step

pySDC/playgrounds/dedalus/interface/problem.py

Lines changed: 84 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,56 +18,115 @@
1818

1919

2020
# -----------------------------------------------------------------------------
21-
# Tentative for a cleaner interface between pySDC and Dedalus
21+
# Tentative for a cleaner interface for pySDC
2222
# -----------------------------------------------------------------------------
23-
class Tendencies(object):
23+
class FValues(object):
2424

25-
def __init__(self):
26-
# TODO : constructor requirements ?
27-
# -> Step.init_step : copy of initial tendency with u[0] = P.dtype_u(u0)
28-
self.terms = []
25+
def copy(self) -> "FValues":
26+
# TODO : return a copy of itself
27+
raise NotImplementedError
2928

30-
def __iadd__(self, f:"Tendencies") -> "Tendencies":
29+
class Tendency(object):
30+
31+
def __iadd__(self, f:FValues) -> "Tendency":
3132
# TODO : inplace addition with other full tendencies
32-
pass
33+
raise NotImplementedError
3334

34-
def axpy(self, a:float|list[float], x:"Tendencies") -> "Tendencies":
35-
if isinstance(a, float):
35+
def axpy(self, a:float, x:FValues|"Tendency") -> "Tendency":
36+
# Note : if a == 0, this should be a no-op ... or better, assert a != 0
37+
if isinstance(x, FValues):
3638
# TODO : y += a*x when x contains all tendencies
3739
pass
38-
if isinstance(a, list):
39-
# TODO : y += a1*x1 + a2*x2 + ... when x1, x2 are each tendency
40-
# Note : if some a[i] are zeros, it should be a no-op
40+
if isinstance(x, Tendency):
41+
# TODO : y += a*x when x is only one tendency
4142
pass
42-
raise ValueError("wrong type for a")
43+
raise ValueError("wrong type for x")
4344

44-
45-
class Solution(object):
45+
class UValues(object):
4646

4747
def __init__(self, init=None, val=0.0):
4848
# TODO : constructor requirements ?
49-
pass
49+
# -> Step.init_step : copy of initial tendency with u[0] = P.dtype_u(u0)
50+
if isinstance(init, UValues):
51+
pass
52+
else:
53+
pass
54+
55+
56+
def setValues(self, other:"UValues"):
57+
# TODO : copy other values into current instance
58+
raise NotImplementedError
59+
60+
def toTendency(self) -> Tendency:
61+
"""Convert into a Tendency instance"""
62+
raise NotImplementedError
63+
5064

51-
class DProblem(Problem):
5265

53-
dtype_u = Solution
54-
dtype_f = Tendencies
66+
class BaseProblem(Problem):
5567

56-
def eval_f(self, u:Solution, t:float, f:Tendencies) -> Tendencies:
57-
# TODO : inplace modify f with the tendencies evaluation
68+
dtype_u = UValues
69+
dtype_f = FValues
70+
71+
def eval_f(self, u:UValues, t:float, f:FValues) -> FValues:
72+
# TODO : inplace evaluate f(u, t)
73+
raise NotImplementedError
74+
75+
def solve_system(self, rhs:Tendency, dt:float, u:UValues, t:float) -> UValues:
76+
# TODO : inplace modify u with the system solve
77+
# u + dt*f_I(u, t) = rhs
78+
# using u as initial solution for an eventual iterative solver
79+
raise NotImplementedError
80+
81+
def apply_mass_matrix(self, u:UValues) -> Tendency:
82+
"""Apply eventual mass matrix on u to produce a tendency (default: no mass matrix)"""
83+
return u.toTendency()
84+
85+
# -----------------------------------------------------------------------------
86+
# Dedalus specific implementation
87+
# -----------------------------------------------------------------------------
88+
class DedalusTendency(Tendency):
89+
90+
def __init__(self):
91+
self.vals:CoeffSystem = None
92+
93+
def __iadd__(self, f: "DedalusTendency"):
94+
self.vals.data += f.vals.data
95+
return self
96+
97+
def axpy(self, a:float, x:"DedalusTendency"|"DedalusFValues") -> "DedalusTendency":
98+
if isinstance(x, DedalusTendency):
99+
self.vals.data += a*x.vals.data
100+
if isinstance(x, DedalusFValues):
101+
self.vals.data += a*(x.impl.vals.data + x.expl.vals.data)
102+
103+
104+
class DedalusFValues(FValues):
105+
106+
def __init__(self):
107+
self.impl:DedalusTendency = None
108+
self.expl:DedalusTendency = None
109+
110+
111+
class DedalProblem(BaseProblem):
112+
113+
dtype_u = UValues
114+
dtype_f = FValues
115+
116+
def eval_f(self, u:UValues, t:float) -> FValues:
117+
# TODO : evaluate f(u, t)
58118
pass
59119

60-
def solve_system(self, rhs:Tendencies, dt:float, u:Solution, t:float) -> Solution:
120+
def solve_system(self, rhs:Tendency, dt:float, u:UValues, t:float) -> UValues:
61121
# TODO : inplace modify u with the system solve
62122
# u + dt*f_I(u, t) = rhs
63123
# using u as initial solution for an eventual iterative solver
64124
pass
65125

66-
def apply_mass_matrix(self, u:Solution, rhs:Tendencies) -> Tendencies:
126+
def apply_mass_matrix(self, u:UValues, rhs:Tendency) -> Tendency:
67127
# TODO : inplace evaluation in rhs of mass-matrix multiplication
68128
pass
69129

70-
71130
# -----------------------------------------------------------------------------
72131
# First interface
73132
# -----------------------------------------------------------------------------

pySDC/playgrounds/dedalus/problems/periodic1D.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ def buildAdvDiffProblem(nX, listK, nu=0):
2222
It uses an initial solution of the form :
2323
2424
.. math::
25-
u_0 = \sum_{i=0}^{N-1} \cos(k[i]x)
25+
u_0 = \sum_{i=0}^{N-1} \cos(k[i](x-2\pi\phi[i]))
2626
27-
with the list of :math:`k[...]` given as argument.
27+
with the list of :math:`k[...]` given as argument
28+
and the :math:`\phi` values determined using a random normal
29+
distribution between 0 and 1.
2830
2931
Parameters
3032
----------
@@ -59,7 +61,7 @@ def buildAdvDiffProblem(nX, listK, nu=0):
5961

6062
# -- initial solution
6163
x = xbasis.local_grid(dist, scale=1)
62-
u0 = np.sum([np.cos(k*x) for k in listK], axis=0)
64+
u0 = np.sum([np.cos(k*(x - np.random.rand()*2*np.pi)) for k in listK], axis=0)
6365
np.copyto(u['g'], u0)
6466
u0 = u.copy() # store initial field into a copy
6567

0 commit comments

Comments
 (0)