Skip to content

Commit 807c86a

Browse files
committed
beautified problem_classes
1 parent 4d59a85 commit 807c86a

20 files changed

+506
-485
lines changed

projects/parallelSDC/nonlinear_playground.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def main():
3333
problem_params['nu'] = 1
3434
problem_params['nvars'] = 255
3535
problem_params['lambda0'] = 5.0
36-
problem_params['maxiter'] = 50
36+
problem_params['newton_maxiter'] = 50
3737
problem_params['newton_tol'] = 1E-12
3838
problem_params['interval'] = (-5, 5)
3939

projects/parallelSDC/preconditioner_playground.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def main():
119119

120120
problem_params['nu'] = 1
121121
problem_params['lambda0'] = param
122-
problem_params['maxiter'] = 20
122+
problem_params['newton_maxiter'] = 20
123123
problem_params['newton_tol'] = 1E-09
124124
problem_params['interval'] = (-5, 5)
125125

@@ -215,5 +215,5 @@ def plot_iterations():
215215

216216

217217
if __name__ == "__main__":
218-
# main()
218+
main()
219219
plot_iterations()

pySDC/core/Errors.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,10 @@ class ControllerError(Exception):
4646
Error class handling/indicating problems with the controller
4747
"""
4848
pass
49+
50+
51+
class ProblemError(Exception):
52+
"""
53+
Error class handling/indicating problems with the problem classes
54+
"""
55+
pass

pySDC/implementations/problem_classes/AdvectionEquation_1D_FD.py

Lines changed: 51 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
from __future__ import division
22
import numpy as np
33
import scipy.sparse as sp
4-
import scipy.sparse.linalg as sLA
5-
import scipy.linalg as LA
4+
from scipy.sparse.linalg import splu
65

76
from pySDC.core.Problem import ptype
7+
from pySDC.core.Errors import ParameterError, ProblemError
88

99

10+
# noinspection PyUnusedLocal
1011
class advection1d(ptype):
1112
"""
12-
Example implementing the unforced 1D advection equation with periodic BC in [0,1], discretized using upwinding finite differences
13+
Example implementing the unforced 1D advection equation with periodic BC in [0,1],
14+
discretized using upwinding finite differences
1315
1416
Attributes:
1517
A: FD discretization of the gradient operator using upwinding
@@ -21,29 +23,33 @@ def __init__(self, problem_params, dtype_u, dtype_f):
2123
Initialization routine
2224
2325
Args:
24-
problem_params: custom parameters for the example
26+
problem_params (dict): custom parameters for the example
2527
dtype_u: mesh data type (will be passed parent class)
2628
dtype_f: mesh data type (will be passed parent class)
2729
"""
2830

2931
# these parameters will be used later, so assert their existence
30-
assert 'nvars' in problem_params, 'ERROR: need number of nvars for the problem class'
31-
assert 'c' in problem_params, 'ERROR: need advection parameter for the problem class'
32-
assert 'freq' in problem_params, 'ERROR: need frequency parameter for the problem class'
32+
essential_keys = ['nvars', 'c', 'freq']
33+
for key in essential_keys:
34+
if key not in problem_params:
35+
msg = 'need %s to instantiate problem, only got %s' % (key, str(problem_params.keys()))
36+
raise ParameterError(msg)
3337

3438
# we assert that nvars looks very particular here.. this will be necessary for coarsening in space later on
35-
assert (problem_params['nvars'])%2 == 0, 'ERROR: the setup requires nvars = 2^p'
39+
if (problem_params['nvars']) % 2 != 0:
40+
raise ProblemError('setup requires nvars = 2^p')
3641

37-
if not 'order' in problem_params:
42+
if 'order' not in problem_params:
3843
problem_params['order'] = 1
39-
if not 'type' in problem_params:
44+
if 'type' not in problem_params:
4045
problem_params['type'] = 'upwind'
4146

4247
# invoke super init, passing number of dofs, dtype_u and dtype_f
43-
super(advection1d,self).__init__(init=problem_params['nvars'], dtype_u=dtype_u, dtype_f=dtype_f, params=problem_params)
48+
super(advection1d, self).__init__(init=problem_params['nvars'], dtype_u=dtype_u, dtype_f=dtype_f,
49+
params=problem_params)
4450

4551
# compute dx and get discretization matrix A
46-
self.dx = 1.0/self.params.nvars
52+
self.dx = 1.0 / self.params.nvars
4753
self.A = self.__get_A(self.params.nvars, self.params.c, self.dx, self.params.order, self.params.type)
4854

4955
@staticmethod
@@ -52,14 +58,14 @@ def __get_A(N, c, dx, order, type):
5258
Helper function to assemble FD matrix A in sparse format
5359
5460
Args:
55-
N: number of dofs
56-
c: diffusion coefficient
57-
dx: distance between two spatial nodes
58-
order: specifies order of discretization
59-
type: upwind or centered differences
61+
N (int): number of dofs
62+
c (float): diffusion coefficient
63+
dx (float): distance between two spatial nodes
64+
order (int): specifies order of discretization
65+
type (string): upwind or centered differences
6066
6167
Returns:
62-
matrix A in CSC format
68+
scipy.sparse.csc_matrix: matrix A in CSC format
6369
"""
6470

6571
coeff = None
@@ -81,8 +87,7 @@ def __get_A(N, c, dx, order, type):
8187
zero_pos = 4
8288
coeff = 1.0 / 60.0
8389
else:
84-
print("Order " + order + " not implemented.")
85-
exit()
90+
raise ProblemError("Order " + str(order) + " not implemented.")
8691

8792
else:
8893

@@ -111,66 +116,65 @@ def __get_A(N, c, dx, order, type):
111116
coeff = 1.0 / 60.0
112117
zero_pos = 5
113118
else:
114-
print("Order " + order + " not implemented.")
115-
exit()
119+
raise ProblemError("Order " + str(order) + " not implemented.")
116120

117-
dstencil = np.concatenate((stencil, np.delete(stencil,zero_pos-1)))
118-
offsets = np.concatenate(([N-i-1 for i in reversed(range(zero_pos-1))],[i-zero_pos+1 for i in range(zero_pos-1,len(stencil))]))
119-
doffsets = np.concatenate((offsets, np.delete(offsets,zero_pos-1)-N))
121+
dstencil = np.concatenate((stencil, np.delete(stencil, zero_pos - 1)))
122+
offsets = np.concatenate(([N - i - 1 for i in reversed(range(zero_pos - 1))],
123+
[i - zero_pos + 1 for i in range(zero_pos - 1, len(stencil))]))
124+
doffsets = np.concatenate((offsets, np.delete(offsets, zero_pos - 1) - N))
120125

121-
A = c * coeff * (1.0/dx) * sp.diags(dstencil,doffsets,shape=(N,N),format='csc')
126+
A = sp.diags(dstencil, doffsets, shape=(N, N), format='csc')
127+
A *= c * coeff * (1.0 / dx)
122128

123129
return A
124130

125-
126-
def eval_f(self,u,t):
131+
def eval_f(self, u, t):
127132
"""
128133
Routine to evaluate the RHS
129134
130135
Args:
131-
u: current values
132-
t: current time
136+
u (dtype_u): current values
137+
t (float): current time
133138
134139
Returns:
135-
the RHS
140+
dtype_f: the RHS
136141
"""
137142

138143
f = self.dtype_f(self.init)
139-
f.values = -self.A.dot(u.values)
144+
f.values = -1.0 * self.A.dot(u.values)
140145
return f
141146

142-
def solve_system(self,rhs,factor,u0,t):
147+
def solve_system(self, rhs, factor, u0, t):
143148
"""
144-
Simple linear solver for (I-factor*A)u = rhs
149+
Simple linear solver for (I+factor*A)u = rhs
145150
146151
Args:
147-
rhs: right-hand side for the linear system
148-
factor: abbrev. for the node-to-node stepsize (or any other factor required)
149-
u0: initial guess for the iterative solver (not used here so far)
150-
t: current time (e.g. for time-dependent BCs)
152+
rhs (dtype_f): right-hand side for the linear system
153+
factor (float) : abbrev. for the node-to-node stepsize (or any other factor required)
154+
u0 (dtype_u): initial guess for the iterative solver (not used here so far)
155+
t (float): current time (e.g. for time-dependent BCs)
151156
152157
Returns:
153-
solution as mesh
158+
dtype_u: solution as mesh
154159
"""
155160

156161
me = self.dtype_u(self.init)
157-
me.values = sLA.spsolve(sp.eye(self.params.nvars)+factor*self.A,rhs.values)
162+
L = splu(sp.eye(self.params.nvars, format='csc') + factor * self.A)
163+
me.values = L.solve(rhs.values)
158164
return me
159165

160-
def u_exact(self,t):
166+
def u_exact(self, t):
161167
"""
162168
Routine to compute the exact solution at time t
163169
164170
Args:
165-
t: current time
171+
t (float): current time
166172
167173
Returns:
168-
exact solution
174+
dtype_u: exact solution
169175
"""
170176

171177
me = self.dtype_u(self.init)
172-
xvalues = np.array([i*self.dx for i in range(self.params.nvars)])
173-
me.values = np.sin(np.pi*self.params.freq*(xvalues - self.params.c*t))
178+
xvalues = np.array([i * self.dx for i in range(self.params.nvars)])
179+
me.values = np.sin(np.pi * self.params.freq * (xvalues - self.params.c * t))
174180
return me
175-
176-

pySDC/implementations/problem_classes/Auzinger_implicit.py

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,43 @@
33
import numpy as np
44

55
from pySDC.core.Problem import ptype
6+
from pySDC.core.Errors import ParameterError
67

78

9+
# noinspection PyUnusedLocal
810
class auzinger(ptype):
911
"""
1012
Example implementing the Auzinger initial value problem
1113
"""
1214

13-
def __init__(self, cparams, dtype_u, dtype_f):
15+
def __init__(self, problem_params, dtype_u, dtype_f):
1416
"""
1517
Initialization routine
1618
1719
Args:
18-
cparams: custom parameters for the example
20+
problem_params (dict): custom parameters for the example
1921
dtype_u: mesh data type (will be passed parent class)
2022
dtype_f: mesh data type (will be passed parent class)
2123
"""
2224

2325
# these parameters will be used later, so assert their existence
24-
assert 'newton_maxiter' in cparams
25-
assert 'newton_tol' in cparams
26+
essential_keys = ['newton_maxiter', 'newton_tol']
27+
for key in essential_keys:
28+
if key not in problem_params:
29+
msg = 'need %s to instantiate problem, only got %s' % (key, str(problem_params.keys()))
30+
raise ParameterError(msg)
2631

27-
# add parameters as attributes for further reference
28-
for k, v in cparams.items():
29-
setattr(self, k, v)
3032
# invoke super init, passing dtype_u and dtype_f, plus setting number of elements to 2
31-
super(auzinger, self).__init__(2, dtype_u, dtype_f, cparams)
33+
super(auzinger, self).__init__(2, dtype_u, dtype_f, problem_params)
3234

3335
def u_exact(self, t):
3436
"""
3537
Routine for the exact solution
3638
3739
Args:
38-
t: current time
40+
t (float): current time
3941
Returns:
40-
mesh type containing the exact solution
42+
dtype_u: mesh type containing the exact solution
4143
"""
4244

4345
me = self.dtype_u(self.init)
@@ -50,8 +52,8 @@ def eval_f(self, u, t):
5052
Routine to compute the RHS for both components simultaneously
5153
5254
Args:
53-
t: current time (not used here)
54-
u: the current values
55+
u (dtype_u): the current values
56+
t (float): current time (not used here)
5557
Returns:
5658
RHS, 2 components
5759
"""
@@ -68,13 +70,13 @@ def solve_system(self, rhs, dt, u0, t):
6870
Simple Newton solver for the nonlinear system
6971
7072
Args:
71-
rhs: right-hand side for the nonlinear system
72-
dt: abbrev. for the node-to-node stepsize (or any other factor required)
73-
u0: initial guess for the iterative solver
74-
t: current time (e.g. for time-dependent BCs)
73+
rhs (dtype_f): right-hand side for the nonlinear system
74+
dt (float): abbrev. for the node-to-node stepsize (or any other factor required)
75+
u0 (dtype_u): initial guess for the iterative solver
76+
t (float): current time (e.g. for time-dependent BCs)
7577
7678
Returns:
77-
solution u
79+
dtype_u: solution u
7880
"""
7981

8082
# create new mesh object from u0 and set initial values for iteration
@@ -123,19 +125,6 @@ def solve_system(self, rhs, dt, u0, t):
123125
#
124126
#
125127
# def solve_system_jacobian(self, dfdu, rhs, factor, u0, t):
126-
# """
127-
# Simple linear solver for (I-dtA)u = rhs
128-
#
129-
# Args:
130-
# dfdu: the Jacobian of the RHS of the ODE
131-
# rhs: right-hand side for the linear system
132-
# factor: abbrev. for the node-to-node stepsize (or any other factor required)
133-
# u0: initial guess for the iterative solver (not used here so far)
134-
# t: current time (e.g. for time-dependent BCs)
135-
#
136-
# Returns:
137-
# solution as mesh
138-
# """
139128
#
140129
# me = mesh(2)
141130
# me.values = LA.spsolve(sp.eye(2) - factor * dfdu, rhs.values)

0 commit comments

Comments
 (0)