6
6
@pytest .fixture (params = ("square" , "cube" ))
7
7
def mh (request ):
8
8
if request .param == "square" :
9
- base_msh = UnitSquareMesh (3 , 3 )
9
+ return [ UnitSquareMesh (2 ** r , 2 ** r ) for r in range ( 1 , 4 )]
10
10
elif request .param == "cube" :
11
- base_msh = UnitCubeMesh (2 , 2 , 2 )
12
- return MeshHierarchy (base_msh , 2 )
11
+ return [UnitCubeMesh (2 ** r , 2 ** r , 2 ** r ) for r in range (1 , 4 )]
12
+ else :
13
+ raise ValueError ("Unexpected mesh type" )
13
14
14
15
15
16
@pytest .fixture (params = ["iso" , "alfeld" , "th" ])
@@ -33,35 +34,27 @@ def mixed_element(mh, variant):
33
34
return Vel , Pel
34
35
35
36
36
- def mesh_sizes (mh ):
37
- mesh_size = []
38
- for msh in mh :
39
- DG0 = FunctionSpace (msh , "DG" , 0 )
40
- h = Function (DG0 ).interpolate (CellDiameter (msh ))
41
- with h .dat .vec as hvec :
42
- _ , maxh = hvec .max ()
43
- mesh_size .append (maxh )
44
- return mesh_size
45
-
46
-
47
- def conv_rates (x , h ):
37
+ def conv_rates (x , h = None ):
48
38
x = np .asarray (x )
49
- h = np .asarray (h )
50
- return np .log2 (x [:- 1 ] / x [1 :]) / np .log2 (h [:- 1 ] / h [1 :])
39
+ rates = np .log2 (x [:- 1 ] / x [1 :])
40
+ if h is not None :
41
+ h = np .asarray (h )
42
+ rates /= np .log2 (h [:- 1 ] / h [1 :])
43
+ return rates
51
44
52
45
53
46
@pytest .fixture
54
47
def convergence_test (variant ):
55
48
if variant == "iso" :
56
- def check (uerr , perr , h ):
57
- return (conv_rates (uerr , h )[- 1 ] >= 1.9
49
+ def check (uerr , perr ):
50
+ return (conv_rates (uerr )[- 1 ] >= 1.9
58
51
and np .allclose (perr , 0 , atol = 1.e-8 ))
59
52
elif variant == "alfeld" :
60
- def check (uerr , perr , h ):
53
+ def check (uerr , perr ):
61
54
return (np .allclose (uerr , 0 , atol = 5.e-9 )
62
55
and np .allclose (perr , 0 , atol = 5.e-7 ))
63
56
elif variant == "th" :
64
- def check (uerr , perr , h ):
57
+ def check (uerr , perr ):
65
58
return (np .allclose (uerr , 0 , atol = 1.e-10 )
66
59
and np .allclose (perr , 0 , atol = 1.e-8 ))
67
60
return check
@@ -112,7 +105,7 @@ def test_riesz(mh, variant, mixed_element, convergence_test):
112
105
u_err .append (errornorm (as_vector (zexact [:dim ]), uh ))
113
106
p_err .append (errornorm (zexact [- 1 ], ph ))
114
107
115
- assert convergence_test (u_err , p_err , mesh_sizes ( mh ) )
108
+ assert convergence_test (u_err , p_err )
116
109
117
110
118
111
def stokes_mms (Z , zexact ):
@@ -121,7 +114,7 @@ def stokes_mms(Z, zexact):
121
114
u , p = split (trial )
122
115
v , q = split (test )
123
116
124
- a = (inner (grad (u ), grad (v )) * dx
117
+ a = (inner (grad (u ) + grad ( u ). T , grad (v )) * dx
125
118
- inner (p , div (v )) * dx
126
119
- inner (div (u ), q ) * dx )
127
120
@@ -131,9 +124,8 @@ def stokes_mms(Z, zexact):
131
124
132
125
def errornormL2_0 (pexact , ph ):
133
126
msh = ph .function_space ().mesh ()
134
- vol = assemble (1 * dx (domain = msh ))
135
- err = pexact - ph
136
- return sqrt (abs (assemble (inner (err , err )* dx ) - (1 / vol )* abs (assemble (err * dx ))** 2 ))
127
+ p0 = assemble ((pexact - ph ) * dx ) / assemble (1 * dx (domain = msh ))
128
+ return errornorm (pexact - Constant (p0 ), ph )
137
129
138
130
139
131
def test_stokes (mh , variant , mixed_element , convergence_test ):
@@ -156,17 +148,22 @@ def test_stokes(mh, variant, mixed_element, convergence_test):
156
148
a , L = stokes_mms (Z , as_vector (zexact ))
157
149
bcs = DirichletBC (Z [0 ], as_vector (zexact [:dim ]), "on_boundary" )
158
150
151
+ pconst = VectorSpaceBasis (constant = True , comm = Z .comm )
152
+ nullspace = MixedVectorSpaceBasis (Z , [Z .sub (0 ), pconst ])
159
153
zh = Function (Z )
160
- nullspace = MixedVectorSpaceBasis (
161
- Z ,
162
- [Z .sub (0 ), VectorSpaceBasis (constant = True , comm = COMM_WORLD )]
163
- )
164
- solve (a == L , zh , bcs = bcs , nullspace = nullspace , solver_parameters = {"ksp_type" : "gmres" })
154
+ solve (a == L , zh , bcs = bcs ,
155
+ nullspace = nullspace ,
156
+ solver_parameters = {
157
+ "mat_type" : "nest" ,
158
+ "ksp_type" : "gmres" ,
159
+ "ksp_pc_side" : "right" ,
160
+ "pc_type" : "lu" })
161
+
165
162
uh , ph = zh .subfunctions
166
163
u_err .append (errornorm (as_vector (zexact [:dim ]), uh ))
167
164
p_err .append (errornormL2_0 (zexact [- 1 ], ph ))
168
165
169
- assert convergence_test (u_err , p_err , mesh_sizes ( mh ) )
166
+ assert convergence_test (u_err , p_err )
170
167
171
168
172
169
def test_div_free (mh , variant , mixed_element , div_test ):
@@ -179,7 +176,7 @@ def test_div_free(mh, variant, mixed_element, div_test):
179
176
V = VectorFunctionSpace (msh , el1 )
180
177
Q = FunctionSpace (msh , el2 )
181
178
Z = V * Q
182
- a , L = stokes_mms (Z , Constant ([ 0 ] * (dim + 1 )))
179
+ a , L = stokes_mms (Z , zero ( (dim + 1 , )))
183
180
184
181
f = as_vector ([1 ] + [0 ] * (dim - 1 ))
185
182
for k in range (1 , dim ):
0 commit comments