18
18
from pyamg .aggregation .smooth import jacobi_prolongation_smoother , \
19
19
richardson_prolongation_smoother , energy_prolongation_smoother
20
20
21
-
21
+
22
22
__all__ = ['smoothed_aggregation_helmholtz_solver' , 'planewaves' ]
23
23
24
24
def planewaves (X , Y , omega = 1.0 , angles = [0.0 ]):
@@ -34,21 +34,21 @@ def planewaves(X, Y, omega=1.0, angles=[0.0]):
34
34
Helmholtz wave number, Laplace(u) + omega^2 u = f
35
35
angles : {list}
36
36
List of angles in [0, 2 pi] from which to generate planewaves
37
-
37
+
38
38
Returns
39
39
-------
40
40
Array of planewaves
41
-
42
- """
41
+
42
+ """
43
43
44
44
L = 2 * len (angles )
45
45
dimen = max (X .shape )
46
46
W = numpy .zeros ((L , dimen ),dtype = complex )
47
-
47
+
48
48
if L == 0 :
49
49
W = W .T .copy ()
50
50
return W
51
-
51
+
52
52
X = numpy .ravel (X )
53
53
Y = numpy .ravel (Y )
54
54
@@ -61,13 +61,13 @@ def planewaves(X, Y, omega=1.0, angles=[0.0]):
61
61
W [counter ,:] = numpy .real (wave )
62
62
W [counter + 1 ,:] = numpy .imag (wave )
63
63
counter += 2
64
-
64
+
65
65
# write W row-wise for efficiency
66
66
W = W .T .copy ()
67
67
return W
68
68
69
69
def preprocess_planewaves (planewaves , max_levels ):
70
- # Helper function for smoothed_aggregation_solver.
70
+ # Helper function for smoothed_aggregation_solver.
71
71
# Will extend planewaves to a length max_levels list, repeating
72
72
# the final element of planewaves if necessary.
73
73
@@ -87,13 +87,13 @@ def unpack_arg(v):
87
87
else :
88
88
return v ,{}
89
89
90
- def smoothed_aggregation_helmholtz_solver (A , planewaves , use_constant = (True , {'last_level' :0 }),
90
+ def smoothed_aggregation_helmholtz_solver (A , planewaves , use_constant = (True , {'last_level' :0 }),
91
91
symmetry = 'symmetric' , strength = 'symmetric' , aggregate = 'standard' ,
92
92
smooth = ('energy' , {'krylov' : 'gmres' }),
93
93
presmoother = ('gauss_seidel_nr' ,{'sweep' :'symmetric' }),
94
94
postsmoother = ('gauss_seidel_nr' ,{'sweep' :'symmetric' }),
95
95
improve_candidates = 'default' , max_levels = 10 , max_coarse = 100 , ** kwargs ):
96
-
96
+
97
97
"""
98
98
Create a multilevel solver using Smoothed Aggregation (SA) for a 2D Helmholtz operator
99
99
@@ -105,19 +105,19 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
105
105
[pw_0, pw_1, ..., pw_n], where the k-th tuple pw_k is of the form (fn,
106
106
args). fn is a callable and args is a dictionary of arguments for fn.
107
107
This k-th tuple is used to define any new planewaves (i.e., new coarse
108
- grid basis functions) to be appended to the existing B_k at that level.
109
- The function fn must return functions defined on the finest level,
108
+ grid basis functions) to be appended to the existing B_k at that level.
109
+ The function fn must return functions defined on the finest level,
110
110
i.e., a collection of vector(s) of length A.shape[0]. These vectors
111
- are then restricted to the appropriate level, where they enrich the
111
+ are then restricted to the appropriate level, where they enrich the
112
112
coarse space.
113
113
Instead of a tuple, None can be used to stipulate no introduction
114
- of planewaves at that level. If len(planewaves) < max_levels, the
114
+ of planewaves at that level. If len(planewaves) < max_levels, the
115
115
last entry is used to define coarser level planewaves.
116
116
use_constant : {tuple}
117
- Tuple of the form (bool, {'last_level':int}). The boolean denotes
117
+ Tuple of the form (bool, {'last_level':int}). The boolean denotes
118
118
whether to introduce the constant in B at level 0. 'last_level' denotes
119
119
the final level to use the constant in B. That is, if 'last_level' is 1,
120
- then the vector in B corresponding to the constant on level 0 is dropped
120
+ then the vector in B corresponding to the constant on level 0 is dropped
121
121
from B at level 2.
122
122
This is important, because using constant based interpolation beyond
123
123
the Nyquist rate will result in poor solver performance.
@@ -131,7 +131,7 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
131
131
Method used to determine the strength of connection between unknowns of
132
132
the linear system. Method-specific parameters may be passed in using a
133
133
tuple, e.g. strength=('symmetric',{'theta' : 0.25 }). If strength=None,
134
- all nonzero entries of the matrix are considered strong.
134
+ all nonzero entries of the matrix are considered strong.
135
135
See notes below for varying this parameter on a per level basis. Also,
136
136
see notes below for using a predefined strength matrix on each level.
137
137
aggregate : ['standard', 'lloyd', 'naive', ('predefined', {'AggOp' : csr_matrix})]
@@ -159,12 +159,12 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
159
159
max_levels : {integer} : default 10
160
160
Maximum number of levels to be used in the multilevel solver.
161
161
max_coarse : {integer} : default 500
162
- Maximum number of variables permitted on the coarse grid.
162
+ Maximum number of variables permitted on the coarse grid.
163
163
164
164
Other Parameters
165
165
----------------
166
166
coarse_solver : ['splu','lu', ... ]
167
- Solver used at the coarsest level of the MG hierarchy
167
+ Solver used at the coarsest level of the MG hierarchy
168
168
169
169
Returns
170
170
-------
@@ -186,7 +186,7 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
186
186
levels, use a list as input so that the ith entry defines the method at
187
187
the ith level. If there are more levels in the hierarchy than list
188
188
entries, the last entry will define the method for all levels lower.
189
-
189
+
190
190
Examples are:
191
191
smooth=[('jacobi', {'omega':1.0}), None, 'jacobi']
192
192
presmoother=[('block_gauss_seidel', {'sweep':symmetric}), 'sor']
@@ -202,7 +202,7 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
202
202
degree-of-freedom in C0 represents a supernode. For instance to
203
203
predefine a three-level hierarchy, use [('predefined', {'C' : C0}),
204
204
('predefined', {'C' : C1}) ].
205
-
205
+
206
206
Similarly for predefined aggregation, use a list of tuples. For instance
207
207
to predefine a three-level hierarchy, use [('predefined', {'AggOp' :
208
208
Agg0}), ('predefined', {'AggOp' : Agg1}) ], where the dimensions of A,
@@ -231,14 +231,14 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
231
231
raise TypeError ('argument A must have type csr_matrix or bsr_matrix' )
232
232
233
233
A = A .asfptype ()
234
-
234
+
235
235
if (symmetry != 'symmetric' ) and (symmetry != 'hermitian' ) and (symmetry != 'nonsymmetric' ):
236
236
raise ValueError ('expected \' symmetric\' , \' nonsymmetric\' or \' hermitian\' for the symmetry parameter ' )
237
237
A .symmetry = symmetry
238
238
239
239
if A .shape [0 ] != A .shape [1 ]:
240
240
raise ValueError ('expected square matrix' )
241
-
241
+
242
242
##
243
243
# Preprocess and extend planewaves to length max_levels
244
244
planewaves = preprocess_planewaves (planewaves , max_levels )
@@ -249,14 +249,14 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
249
249
first_planewave_level += 1
250
250
if pw is not None :
251
251
break
252
- ##
252
+ ##
253
253
if (use_const == False ) and (planewaves [0 ] == None ):
254
254
raise ValueError ('No functions defined for B on the finest level, ' + \
255
255
'either use_constant must be true, or planewaves must be defined for level 0' )
256
256
elif (use_const == True ) and (args ['last_level' ] < first_planewave_level - 1 ):
257
257
raise ValueError ('Some levels have no function(s) defined for B. ' + \
258
258
'Change use_constant and/or planewave arguments.' )
259
-
259
+
260
260
##
261
261
# Levelize the user parameters, so that they become lists describing the
262
262
# desired user option on each level.
@@ -291,7 +291,7 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
291
291
# As in alpha-SA, relax the candidates before restriction
292
292
if improve_candidates [0 ] is not None :
293
293
Bcoarse2 = relaxation_as_linear_operator (improve_candidates [0 ], A , zeros_0 )* Bcoarse2
294
-
294
+
295
295
##
296
296
# Restrict Bcoarse2 to current level
297
297
for i in range (len (levels )- 1 ):
@@ -308,17 +308,17 @@ def smoothed_aggregation_helmholtz_solver(A, planewaves, use_constant=(True, {'l
308
308
if use_const and len (levels ) == 1 :
309
309
# If level 0, and the constant is to be used in interpolation
310
310
levels [0 ].B = numpy .hstack ( (numpy .ones ((A .shape [0 ],1 ), dtype = A .dtype ), Bcoarse2 ) )
311
- elif use_const and args ['last_level' ] == len (levels )- 2 :
311
+ elif use_const and args ['last_level' ] == len (levels )- 2 :
312
312
# If the previous level was the last level to use the constant, then remove the
313
313
# coarse grid function based on the constant from B
314
314
levels [- 1 ].B = numpy .hstack ( (levels [- 1 ].B [:,1 :], Bcoarse2 ) )
315
315
else :
316
316
levels [- 1 ].B = numpy .hstack ((levels [- 1 ].B , Bcoarse2 ))
317
-
317
+
318
318
##
319
319
# Create and Append new level
320
320
_extend_hierarchy (levels , strength , aggregate , smooth , [None for i in range (max_levels )] ,keep = True )
321
-
321
+
322
322
ml = multilevel_solver (levels , ** kwargs )
323
323
change_smoothers (ml , presmoother , postsmoother )
324
324
return ml
0 commit comments