11import numpy as np
2- import scipy .sparse as sp
3- import scipy .sparse .linalg as spla
42
53from pySDC .implementations .controller_classes .allinclusive_multigrid_nonMPI import allinclusive_multigrid_nonMPI
64
@@ -55,16 +53,16 @@ def __init__(self, num_procs, controller_params, description):
5553 assert self .nlevels <= 2 , 'ERROR: cannot use matrix-PFASST with more than 2 levels' # TODO: fixme
5654 assert [level .dt for step in self .MS for level in step .levels ].count (self .dt ) == self .nlevels * self .nsteps , \
5755 'ERROR: dt must be equal for all steps and all levels'
58- assert [level .sweep .coll .num_nodes for step in self .MS for level in step .levels ].count (self .nnodes ) == \
59- self .nlevels * self .nsteps , 'ERROR: nnodes must be equal for all steps and all levels'
56+ # assert [level.sweep.coll.num_nodes for step in self.MS for level in step.levels].count(self.nnodes) == \
57+ # self.nlevels * self.nsteps, 'ERROR: nnodes must be equal for all steps and all levels'
6058 assert [type (level .prob ) for step in self .MS for level in step .levels ].count (type (prob )) == \
6159 self .nlevels * self .nsteps , 'ERROR: all probem classes have to be the same'
6260
6361 assert self .params .predict is False , 'ERROR: no predictor for matrix controller yet' # TODO: fixme
6462
6563 assert hasattr (prob , 'A' ), 'ERROR: need system matrix A for this (and linear problems!)'
6664
67- A = prob .A
65+ A = prob .A . todense ()
6866 Q = self .MS [0 ].levels [0 ].sweep .coll .Qmat [1 :, 1 :]
6967 Qd = self .MS [0 ].levels [0 ].sweep .QI [1 :, 1 :]
7068
@@ -74,26 +72,33 @@ def __init__(self, num_procs, controller_params, description):
7472 N = np .zeros ((self .nnodes , self .nnodes ))
7573 N [:, - 1 ] = 1
7674
77- self .C = sp .eye (self .nsteps * self .nnodes * self .nspace ) - \
78- self .dt * sp .kron (sp .eye (self .nsteps ), sp .kron (Q , A )) - sp .kron (E , sp .kron (N , sp .eye (self .nspace )))
79- self .P = sp .eye (self .nsteps * self .nnodes * self .nspace ) - \
80- self .dt * sp .kron (sp .eye (self .nsteps ), sp .kron (Qd , A ))
75+ self .C = np . array ( np .eye (self .nsteps * self .nnodes * self .nspace ) - \
76+ self .dt * np .kron (np .eye (self .nsteps ), np .kron (Q , A )) - np .kron (E , np .kron (N , np .eye (self .nspace ) )))
77+ self .P = np . array ( np .eye (self .nsteps * self .nnodes * self .nspace ) - \
78+ self .dt * np .kron (np .eye (self .nsteps ), np .kron (Qd , A ) ))
8179
8280 if self .nlevels > 1 :
8381 prob_c = self .MS [0 ].levels [1 ].prob
8482 self .nspace_c = prob_c .init
8583
86- Ac = prob_c .A
84+ Ac = prob_c .A . todense ()
8785 Qdc = self .MS [0 ].levels [1 ].sweep .QI [1 :, 1 :]
8886
89- TcfA = self .MS [0 ].base_transfer .space_transfer .Pspace
90- TfcA = self .MS [0 ].base_transfer .space_transfer .Rspace
87+ nnodesc = self .MS [0 ].levels [1 ].sweep .coll .num_nodes
88+ Nc = np .zeros ((nnodesc , nnodesc ))
89+ Nc [:, - 1 ] = 1
9190
92- self .Tcf = sp .kron (sp .eye (self .nsteps * self .nnodes ), TcfA )
93- self .Tfc = sp .kron (sp .eye (self .nsteps * self .nnodes ), TfcA )
91+ TcfA = self .MS [0 ].base_transfer .space_transfer .Pspace .todense ()
92+ TfcA = self .MS [0 ].base_transfer .space_transfer .Rspace .todense ()
93+ TcfQ = self .MS [0 ].base_transfer .Pcoll
94+ TfcQ = self .MS [0 ].base_transfer .Rcoll
9495
95- self .Pc = sp .eye (self .nsteps * self .nnodes * self .nspace_c ) - \
96- self .dt * sp .kron (sp .eye (self .nsteps ), sp .kron (Qdc , Ac )) - sp .kron (E , sp .kron (N , sp .eye (self .nspace_c )))
96+ self .Tcf = np .array (np .kron (np .eye (self .nsteps ), np .kron (TcfQ , TcfA )))
97+ self .Tfc = np .array (np .kron (np .eye (self .nsteps ), np .kron (TfcQ , TfcA )))
98+
99+ self .Pc = np .array (np .eye (self .nsteps * nnodesc * self .nspace_c ) - \
100+ self .dt * np .kron (np .eye (self .nsteps ), np .kron (Qdc , Ac )) - \
101+ np .kron (E , np .kron (Nc , np .eye (self .nspace_c ))))
97102
98103 self .u = np .zeros (self .nsteps * self .nnodes * self .nspace )
99104 self .res = np .zeros (self .nsteps * self .nnodes * self .nspace )
@@ -167,9 +172,9 @@ def build_propagation_matrix(self, niter):
167172 """
168173
169174 # build smoother iteration matrix and preconditioner using nsweeps
170- Pinv = np .linalg .inv (self .P . todense () )
175+ Pinv = np .linalg .inv (self .P )
171176 precond_smoother = Pinv .copy ()
172- iter_mat_smoother = np .eye (self .nsteps * self .nnodes * self .nspace ) - precond_smoother .dot (self .C . todense () )
177+ iter_mat_smoother = np .eye (self .nsteps * self .nnodes * self .nspace ) - precond_smoother .dot (self .C )
173178 for k in range (1 , self .MS [0 ].levels [0 ].params .nsweeps ):
174179 precond_smoother += np .linalg .matrix_power (iter_mat_smoother , k ).dot (Pinv )
175180 iter_mat_smoother = np .linalg .matrix_power (iter_mat_smoother , self .MS [0 ].levels [0 ].params .nsweeps )
@@ -178,10 +183,10 @@ def build_propagation_matrix(self, niter):
178183
179184 # add coarse-grid correction (single sweep, though!)
180185 if self .nlevels > 1 :
181- precond_cgc = self .Tcf .todense (). dot (np .linalg .inv (self .Pc . todense ())) .dot (self .Tfc . todense () )
182- iter_mat_cgc = np .eye (self .nsteps * self .nnodes * self .nspace ) - precond_cgc .dot (self .C . todense () )
186+ precond_cgc = self .Tcf .dot (np .linalg .inv (self .Pc )) .dot (self .Tfc )
187+ iter_mat_cgc = np .eye (self .nsteps * self .nnodes * self .nspace ) - precond_cgc .dot (self .C )
183188 iter_mat = iter_mat .dot (iter_mat_cgc )
184- precond += precond_cgc - precond_smoother .dot (self .C . todense () ).dot (precond_cgc )
189+ precond += precond_cgc - precond_smoother .dot (self .C ).dot (precond_cgc )
185190
186191 # form span and reduce matrices and add to operator
187192 Tspread = np .kron (np .concatenate ([[1 ] * (self .nsteps * self .nnodes )]), np .eye (self .nspace )).T
@@ -223,7 +228,7 @@ def restart_block(self, slots, time, u0):
223228 for lvl in self .MS [p ].levels :
224229 lvl .status .time = time [p ]
225230 P = lvl .prob
226- for m in range (1 , self . nnodes + 1 ):
231+ for m in range (1 , lvl . sweep . coll . num_nodes + 1 ):
227232 lvl .u [m ] = P .dtype_u (init = P .init , val = 0 )
228233 lvl .f [m ] = P .dtype_f (init = P .init , val = 0 )
229234
@@ -288,7 +293,7 @@ def pfasst(self, MS):
288293 for S in MS :
289294 self .hooks .pre_sweep (step = S , level_number = 0 )
290295
291- self .u += spla . spsolve (self .P , self .res )
296+ self .u += np . linalg . solve (self .P , self .res )
292297 self .res = self .u0 - self .C .dot (self .u )
293298
294299 MS = self .update_data (MS = MS , u = self .u , res = self .res , niter = niter , level = 0 , stage = 'POST_PRE_SWEEP' )
@@ -310,7 +315,7 @@ def pfasst(self, MS):
310315 for S in MS :
311316 self .hooks .pre_sweep (step = S , level_number = 1 )
312317
313- self .u += self .Tcf .dot (spla . spsolve (self .Pc , self .Tfc .dot (self .res )))
318+ self .u += self .Tcf .dot (np . linalg . solve (self .Pc , self .Tfc .dot (self .res )))
314319 self .res = self .u0 - self .C .dot (self .u )
315320
316321 MS = self .update_data (MS = MS , u = self .u , res = self .res , niter = niter , level = 1 ,
@@ -324,7 +329,7 @@ def pfasst(self, MS):
324329 for S in MS :
325330 self .hooks .pre_sweep (step = S , level_number = 0 )
326331
327- self .u += spla . spsolve (self .P , self .res )
332+ self .u += np . linalg . solve (self .P , self .res )
328333 self .res = self .u0 - self .C .dot (self .u )
329334
330335 MS = self .update_data (MS = MS , u = self .u , res = self .res , niter = niter , level = 0 , stage = 'POST_FINE_SWEEP' )
0 commit comments