MCPcopy Create free account
hub / github.com/FEniCS/dolfinx / cg_solver

Function cg_solver

python/test/conftest.py:150–200  ·  view source on GitHub ↗

Conjugate Gradient solver for SPD problems, which can work in serial or parallel for testing use. Not suitable for large problems.

()

Source from the content-addressed store, hash-verified

148
149@pytest.fixture(scope="function", autouse=True)
150def cg_solver():
151 """Conjugate Gradient solver for SPD problems, which can work in
152 serial or parallel for testing use. Not suitable for large
153 problems.
154 """
155
156 def _cg(comm, A, b, x, maxit=500, rtol=None):
157 rtol2 = 10 * np.finfo(x.array.dtype).eps if rtol is None else rtol**2
158
159 def _global_dot(comm, v0, v1):
160 return comm.allreduce(np.vdot(v0, v1), MPI.SUM)
161
162 A_op = A.to_scipy()
163 nr = A_op.shape[0]
164 assert nr == A.index_map(0).size_local * A.block_size[0]
165
166 # Create larger ghosted vector based on matrix column space
167 # and get initial y = A.x
168 p = dolfinx_vector(A.index_map(1), bs=A.block_size[1], dtype=x.array.dtype)
169 p.array[:nr] = x.array[:nr]
170 p.scatter_forward()
171 y = A_op @ p.array
172
173 # Copy residual to p
174 r = b.array[:nr] - y
175 p.array[:nr] = r
176
177 # Iterations of CG
178 rnorm0 = _global_dot(comm, r, r)
179 rnorm = rnorm0
180 k = 0
181 while k < maxit:
182 k += 1
183 p.scatter_forward()
184 y = A_op @ p.array
185 alpha = rnorm / _global_dot(comm, p.array[:nr], y)
186 x.array[:nr] += alpha * p.array[:nr]
187 r -= alpha * y
188 rnorm_new = _global_dot(comm, r, r)
189 beta = rnorm_new / rnorm
190 rnorm = rnorm_new
191 if rnorm / rnorm0 < rtol2:
192 x.scatter_forward()
193 return
194 p.array[:nr] = beta * p.array[:nr] + r
195
196 raise RuntimeError(
197 f"Solver exceeded max iterations ({maxit}). Relative residual={rnorm / rnorm0}."
198 )
199
200 return _cg

Callers 5

run_scalar_testFunction · 0.85
run_vector_testFunction · 0.85
run_dg_testFunction · 0.85
run_scalar_testFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected