6
6
import numpy as np
7
7
import pytest
8
8
from conftest import ComplexGeneratorFromMatrix , GeneratorFromMatrix
9
- from scipy .linalg import eig , eigh
9
+ from scipy .linalg import eig , eigh , ldl , solve_triangular
10
+ from scipy .sparse .linalg import LinearOperator , eigsh
10
11
11
12
12
- class CustomGeneoCoarseSpaceDenseBuilder (Htool .VirtualGeneoCoarseSpaceDenseBuilder ):
13
+ class CustomDenseGeneoCoarseSpaceDenseBuilder (
14
+ Htool .VirtualGeneoCoarseSpaceDenseBuilder
15
+ ):
13
16
def compute_coarse_space (self , Ai , Bi ):
14
17
coarse_space = None
15
18
if self .symmetry == "S" or self .symmetry == "H" :
@@ -30,6 +33,102 @@ def compute_coarse_space(self, Ai, Bi):
30
33
self .set_coarse_space (coarse_space )
31
34
32
35
36
+ class CustomGeneoCoarseSpaceBuilder (Htool .VirtualGeneoCoarseSpaceBuilder ):
37
+ class DirichletHMatrix (LinearOperator ):
38
+ def __init__ (self , hmatrix_callback , size , dtype ):
39
+ self .hmatrix_callback = hmatrix_callback
40
+ self .shape = (size , size )
41
+ self .dtype = dtype
42
+
43
+ def _matvec (self , x ):
44
+ return self .hmatrix_callback (x )
45
+
46
+ class DenseNeumannMatrix (LinearOperator ):
47
+ def __init__ (self , Bi ):
48
+ self .L , self .D , self .perm = ldl (Bi )
49
+ self .shape = Bi .shape
50
+ self .dtype = Bi .dtype
51
+
52
+ def _matvec (self , x ):
53
+ tmp = solve_triangular (self .L [self .perm , :], x [self .perm ], lower = True )
54
+ for index , coef in enumerate (self .D .diagonal ()):
55
+ # if coef>1e-4:
56
+ tmp [index ] /= coef
57
+ # else :
58
+ # tmp[index]=0
59
+ res = np .empty_like (x )
60
+ res [self .perm ] = solve_triangular (
61
+ self .L [self .perm , :], tmp , lower = True , trans = "T"
62
+ )
63
+ return res
64
+
65
+ def __init__ (
66
+ self ,
67
+ size_wo_overlap ,
68
+ size_with_overlap ,
69
+ Ai ,
70
+ Bi ,
71
+ geneo_nu = 2 ,
72
+ geneo_threshold = None ,
73
+ ):
74
+ if not geneo_threshold :
75
+ Htool .VirtualGeneoCoarseSpaceBuilder .__init__ (
76
+ self ,
77
+ size_wo_overlap ,
78
+ size_with_overlap ,
79
+ Ai ,
80
+ geneo_nu = geneo_nu ,
81
+ )
82
+ else :
83
+ Htool .VirtualGeneoCoarseSpaceBuilder .__init__ (
84
+ self ,
85
+ size_wo_overlap ,
86
+ size_with_overlap ,
87
+ Ai ,
88
+ geneo_threshold = geneo_threshold ,
89
+ )
90
+ self .local_size = size_with_overlap
91
+ self .Bi = Bi
92
+ self .Ai = Ai
93
+
94
+ def compute_coarse_space (self , hmatrix_callback ):
95
+ self .coarse_space = None
96
+ self .eigenvalues = None
97
+
98
+ if self .geneo_threshold > 0 :
99
+ [w , v ] = eigsh (
100
+ self .Bi ,
101
+ 10 ,
102
+ M = self .DirichletHMatrix (
103
+ hmatrix_callback , self .local_size , np .dtype ("float64" )
104
+ ),
105
+ OPinv = self .DenseNeumannMatrix (self .Bi ),
106
+ return_eigenvectors = True ,
107
+ sigma = 0 ,
108
+ )
109
+ else :
110
+ [w , v ] = eigsh (
111
+ self .Bi ,
112
+ self .geneo_nu ,
113
+ M = self .DirichletHMatrix (
114
+ hmatrix_callback , self .local_size , np .dtype ("float64" )
115
+ ),
116
+ OPinv = self .DenseNeumannMatrix (self .Bi ),
117
+ return_eigenvectors = True ,
118
+ sigma = 0 ,
119
+ )
120
+ idx = w .argsort ()
121
+ if self .geneo_threshold > 0 :
122
+ nb_eig = (w < 1.0 / self .geneo_threshold ).sum ()
123
+ self .coarse_space = v [:, idx [0 :nb_eig ]].real
124
+ self .eigenvalues = 1.0 / w [idx [:]]
125
+ else :
126
+ self .coarse_space = v [:, idx [0 : self .geneo_nu ]]
127
+ self .eigenvalues = 1.0 / w [idx [:]]
128
+
129
+ self .set_coarse_space (self .coarse_space )
130
+
131
+
33
132
@pytest .mark .parametrize ("epsilon" , [1e-6 ])
34
133
@pytest .mark .parametrize ("eta" , [10 ])
35
134
@pytest .mark .parametrize ("tol" , [1e-6 ])
@@ -96,6 +195,70 @@ def compute_coarse_space(self, Ai, Bi):
96
195
"additive" ,
97
196
"geneo_threshold" ,
98
197
),
198
+ (
199
+ 1 ,
200
+ "S" ,
201
+ "DDMWithHMatrixPlusOverlap" ,
202
+ "asm" ,
203
+ "additive" ,
204
+ "custom_dense_geneo_nu" ,
205
+ ),
206
+ (
207
+ 1 ,
208
+ "S" ,
209
+ "DDMWithHMatrixPlusOverlap" ,
210
+ "ras" ,
211
+ "additive" ,
212
+ "custom_dense_geneo_nu" ,
213
+ ),
214
+ (
215
+ 10 ,
216
+ "S" ,
217
+ "DDMWithHMatrixPlusOverlap" ,
218
+ "asm" ,
219
+ "additive" ,
220
+ "custom_dense_geneo_nu" ,
221
+ ),
222
+ (
223
+ 10 ,
224
+ "S" ,
225
+ "DDMWithHMatrixPlusOverlap" ,
226
+ "ras" ,
227
+ "additive" ,
228
+ "custom_dense_geneo_nu" ,
229
+ ),
230
+ (
231
+ 1 ,
232
+ "S" ,
233
+ "DDMWithHMatrixPlusOverlap" ,
234
+ "asm" ,
235
+ "additive" ,
236
+ "custom_dense_geneo_threshold" ,
237
+ ),
238
+ (
239
+ 1 ,
240
+ "S" ,
241
+ "DDMWithHMatrixPlusOverlap" ,
242
+ "ras" ,
243
+ "additive" ,
244
+ "custom_dense_geneo_threshold" ,
245
+ ),
246
+ (
247
+ 10 ,
248
+ "S" ,
249
+ "DDMWithHMatrixPlusOverlap" ,
250
+ "asm" ,
251
+ "additive" ,
252
+ "custom_dense_geneo_threshold" ,
253
+ ),
254
+ (
255
+ 10 ,
256
+ "S" ,
257
+ "DDMWithHMatrixPlusOverlap" ,
258
+ "ras" ,
259
+ "additive" ,
260
+ "custom_dense_geneo_threshold" ,
261
+ ),
99
262
(1 , "S" , "DDMWithHMatrixPlusOverlap" , "asm" , "additive" , "custom_geneo_nu" ),
100
263
(1 , "S" , "DDMWithHMatrixPlusOverlap" , "ras" , "additive" , "custom_geneo_nu" ),
101
264
(
@@ -156,6 +319,14 @@ def compute_coarse_space(self, Ai, Bi):
156
319
(1 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "geneo_threshold" ),
157
320
(10 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "geneo_threshold" ),
158
321
(10 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "geneo_threshold" ),
322
+ (1 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_dense_geneo_nu" ),
323
+ (1 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "custom_dense_geneo_nu" ),
324
+ (10 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_dense_geneo_nu" ),
325
+ (10 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "custom_dense_geneo_nu" ),
326
+ (1 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_dense_geneo_threshold" ),
327
+ (1 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "custom_dense_geneo_threshold" ),
328
+ (10 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_dense_geneo_threshold" ),
329
+ (10 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "custom_dense_geneo_threshold" ),
159
330
(1 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_geneo_nu" ),
160
331
(1 , "S" , "DDMWithHMatrix" , "ras" , "additive" , "custom_geneo_nu" ),
161
332
(10 , "S" , "DDMWithHMatrix" , "asm" , "additive" , "custom_geneo_nu" ),
@@ -383,7 +554,24 @@ def test_ddm_solver(
383
554
geneo_threshold = 100 ,
384
555
)
385
556
elif geneo_type == "custom_geneo_nu" :
386
- geneo_space_operator_builder = CustomGeneoCoarseSpaceDenseBuilder (
557
+ print ("ICI" )
558
+ geneo_space_operator_builder = CustomGeneoCoarseSpaceBuilder (
559
+ local_size_wo_overlap ,
560
+ local_size_with_overlap ,
561
+ default_approximation .block_diagonal_hmatrix ,
562
+ local_neumann_matrix ,
563
+ geneo_nu = 2 ,
564
+ )
565
+ elif geneo_type == "custom_geneo_threshold" :
566
+ geneo_space_operator_builder = CustomGeneoCoarseSpaceBuilder (
567
+ local_size_wo_overlap ,
568
+ local_size_with_overlap ,
569
+ default_approximation .block_diagonal_hmatrix ,
570
+ local_neumann_matrix ,
571
+ geneo_threshold = 100 ,
572
+ )
573
+ elif geneo_type == "custom_dense_geneo_nu" :
574
+ geneo_space_operator_builder = CustomDenseGeneoCoarseSpaceDenseBuilder (
387
575
local_size_wo_overlap ,
388
576
local_size_with_overlap ,
389
577
default_approximation .block_diagonal_hmatrix .to_dense (),
@@ -392,8 +580,8 @@ def test_ddm_solver(
392
580
UPLO ,
393
581
geneo_nu = 2 ,
394
582
)
395
- elif geneo_type == "custom_geneo_threshold " :
396
- geneo_space_operator_builder = CustomGeneoCoarseSpaceDenseBuilder (
583
+ elif geneo_type == "custom_dense_geneo_threshold " :
584
+ geneo_space_operator_builder = CustomDenseGeneoCoarseSpaceDenseBuilder (
397
585
local_size_wo_overlap ,
398
586
local_size_with_overlap ,
399
587
default_approximation .block_diagonal_hmatrix .to_dense (),
0 commit comments