Skip to content

Commit 3b5a2a5

Browse files
committed
much faster Newton solver, still slow
1 parent d2d49c2 commit 3b5a2a5

File tree

2 files changed

+54
-32
lines changed

2 files changed

+54
-32
lines changed

pySDC/implementations/problem_classes/GrayScott_MPIFFT.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import numpy as np
2+
import scipy.sparse as sp
23
from mpi4py import MPI
34
from mpi4py_fft import PFFT
45

@@ -380,12 +381,23 @@ def solve_system_2(self, rhs, factor, u0, t):
380381
dg10 = -factor * (tmpv ** 2)
381382
dg11 = 1 - factor * (2 * tmpu * tmpv - self.params.B)
382383

383-
for ix, iy in np.ndindex(tmpu.shape):
384-
a = np.array([tmpgu[ix, iy], tmpgv[ix, iy]])
385-
dg = np.array([[dg00[ix, iy], dg01[ix, iy]], [dg10[ix, iy], dg11[ix, iy]]])
386-
b = np.linalg.inv(dg).dot(a)
387-
tmpu[ix, iy] -= b[0]
388-
tmpv[ix, iy] -= b[1]
384+
# interleave and unravel to put into sparse matrix
385+
dg00I = np.ravel(np.kron(dg00, np.array([1, 0])))
386+
dg01I = np.ravel(np.kron(dg01, np.array([1, 0])))
387+
dg10I = np.ravel(np.kron(dg10, np.array([1, 0])))
388+
dg11I = np.ravel(np.kron(dg11, np.array([0, 1])))
389+
390+
# put into sparse matrix
391+
dg = sp.diags(dg00I, offsets=0) + sp.diags(dg11I, offsets=0)
392+
dg += sp.diags(dg01I, offsets=1, shape=dg.shape) + sp.diags(dg10I, offsets=-1, shape=dg.shape)
393+
394+
# interleave g terms to apply inverse to it
395+
g = np.kron(tmpgu.flatten(), np.array([1, 0])) + np.kron(tmpgv.flatten(), np.array([0, 1]))
396+
# invert dg matrix
397+
b = sp.linalg.spsolve(dg, g)
398+
# update real space vectors
399+
tmpu[:] -= b[::2].reshape(self.params.nvars)
400+
tmpv[:] -= b[1::2].reshape(self.params.nvars)
389401

390402
# increase iteration count
391403
n += 1
@@ -535,12 +547,23 @@ def solve_system_2(self, rhs, factor, u0, t):
535547
dg10 = -factor * (tmpv ** 2)
536548
dg11 = 1 - factor * (2 * tmpu * tmpv)
537549

538-
for ix, iy in np.ndindex(tmpu.shape):
539-
a = np.array([tmpgu[ix, iy], tmpgv[ix, iy]])
540-
dg = np.array([[dg00[ix, iy], dg01[ix, iy]], [dg10[ix, iy], dg11[ix, iy]]])
541-
b = np.linalg.inv(dg).dot(a)
542-
tmpu[ix, iy] -= b[0]
543-
tmpv[ix, iy] -= b[1]
550+
# interleave and unravel to put into sparse matrix
551+
dg00I = np.ravel(np.kron(dg00, np.array([1, 0])))
552+
dg01I = np.ravel(np.kron(dg01, np.array([1, 0])))
553+
dg10I = np.ravel(np.kron(dg10, np.array([1, 0])))
554+
dg11I = np.ravel(np.kron(dg11, np.array([0, 1])))
555+
556+
# put into sparse matrix
557+
dg = sp.diags(dg00I, offsets=0) + sp.diags(dg11I, offsets=0)
558+
dg += sp.diags(dg01I, offsets=1, shape=dg.shape) + sp.diags(dg10I, offsets=-1, shape=dg.shape)
559+
560+
# interleave g terms to apply inverse to it
561+
g = np.kron(tmpgu.flatten(), np.array([1, 0])) + np.kron(tmpgv.flatten(), np.array([0, 1]))
562+
# invert dg matrix
563+
b = sp.linalg.spsolve(dg, g)
564+
# update real-space vectors
565+
tmpu[:] -= b[::2].reshape(self.params.nvars)
566+
tmpv[:] -= b[1::2].reshape(self.params.nvars)
544567

545568
# increase iteration count
546569
n += 1

pySDC/playgrounds/mpifft/grayscott.py

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from pySDC.implementations.sweeper_classes.multi_implicit import multi_implicit
1111
from pySDC.implementations.problem_classes.GrayScott_MPIFFT import grayscott_imex_diffusion, grayscott_imex_linear, \
1212
grayscott_mi_diffusion, grayscott_mi_linear
13-
# from pySDC.implementations.problem_classes.GrayScott_FFT import grayscott_imex_linear
1413
from pySDC.implementations.transfer_classes.TransferMesh_MPIFFT import fft_to_fft
1514

1615

@@ -30,7 +29,7 @@ def run_simulation(spectral=None, splitting_type=None, ml=None, num_procs=None):
3029
# initialize level parameters
3130
level_params = dict()
3231
level_params['restol'] = 1E-12
33-
level_params['dt'] = 1E-00
32+
level_params['dt'] = 8E-00
3433
level_params['nsweeps'] = [1]
3534
level_params['residual_type'] = 'last_abs'
3635

@@ -57,12 +56,12 @@ def run_simulation(spectral=None, splitting_type=None, ml=None, num_procs=None):
5756
problem_params['Dv'] = 0.00001
5857
problem_params['A'] = 0.04
5958
problem_params['B'] = 0.1
60-
problem_params['newton_maxiter'] = 100
59+
problem_params['newton_maxiter'] = 50
6160
problem_params['newton_tol'] = 1E-11
6261

6362
# initialize step parameters
6463
step_params = dict()
65-
step_params['maxiter'] = 500
64+
step_params['maxiter'] = 100
6665
step_params['errtol'] = 1E-09
6766

6867
# initialize controller parameters
@@ -95,7 +94,7 @@ def run_simulation(spectral=None, splitting_type=None, ml=None, num_procs=None):
9594

9695
# set time parameters
9796
t0 = 0.0
98-
Tend = 4
97+
Tend = 32
9998

10099
f = None
101100
if rank == 0:
@@ -127,21 +126,21 @@ def run_simulation(spectral=None, splitting_type=None, ml=None, num_procs=None):
127126
# call main function to get things done...
128127
uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend)
129128

130-
plt.figure()
131-
plt.imshow(P.fft.backward(uend[..., 0]))#, vmin=0, vmax=1)
132-
# plt.imshow(np.fft.irfft2(uend.values[..., 0]))#, vmin=0, vmax=1)
133-
plt.title('u')
134-
plt.colorbar()
135-
plt.figure()
136-
plt.imshow(P.fft.backward(uend[..., 1]))#, vmin=0, vmax=1)
137-
# plt.imshow(np.fft.irfft2(uend.values[..., 1]))#, vmin=0, vmax=1)
138-
plt.title('v')
139-
plt.colorbar()
140129
# plt.figure()
141-
# plt.imshow(uend[..., 0] + uend[..., 1])
142-
# plt.title('sum')
130+
# plt.imshow(P.fft.backward(uend[..., 0]))#, vmin=0, vmax=1)
131+
# # plt.imshow(np.fft.irfft2(uend.values[..., 0]))#, vmin=0, vmax=1)
132+
# plt.title('u')
133+
# plt.colorbar()
134+
# plt.figure()
135+
# plt.imshow(P.fft.backward(uend[..., 1]))#, vmin=0, vmax=1)
136+
# # plt.imshow(np.fft.irfft2(uend.values[..., 1]))#, vmin=0, vmax=1)
137+
# plt.title('v')
143138
# plt.colorbar()
144-
plt.show()
139+
# # plt.figure()
140+
# # plt.imshow(uend[..., 0] + uend[..., 1])
141+
# # plt.title('sum')
142+
# # plt.colorbar()
143+
# plt.show()
145144
# # exit()
146145

147146
if rank == 0:
@@ -185,14 +184,14 @@ def main():
185184
"""
186185
# run_simulation(spectral=False, splitting_type='diffusion', ml=False, num_procs=1)
187186
# run_simulation(spectral=True, splitting_type='diffusion', ml=False, num_procs=1)
188-
run_simulation(spectral=True, splitting_type='linear', ml=False, num_procs=1)
187+
# run_simulation(spectral=True, splitting_type='linear', ml=False, num_procs=1)
189188
# run_simulation(spectral=False, splitting_type='diffusion', ml=True, num_procs=1)
190189
# run_simulation(spectral=True, splitting_type='diffusion', ml=True, num_procs=1)
191190
# run_simulation(spectral=False, splitting_type='diffusion', ml=True, num_procs=10)
192191
# run_simulation(spectral=True, splitting_type='diffusion', ml=True, num_procs=10)
193192

194193
# run_simulation(spectral=False, splitting_type='mi_diffusion', ml=False, num_procs=1)
195-
# run_simulation(spectral=True, splitting_type='mi_diffusion', ml=False, num_procs=1)
194+
run_simulation(spectral=True, splitting_type='mi_diffusion', ml=False, num_procs=1)
196195
# run_simulation(spectral=False, splitting_type='mi_linear', ml=False, num_procs=1)
197196
# run_simulation(spectral=True, splitting_type='mi_linear', ml=False, num_procs=1)
198197

0 commit comments

Comments
 (0)