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

Function _cg

python/test/conftest.py:156–198  ·  view source on GitHub ↗
(comm, A, b, x, maxit=500, rtol=None)

Source from the content-addressed store, hash-verified

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

nothing calls this directly

Calls 4

to_scipyMethod · 0.80
scatter_forwardMethod · 0.80
_global_dotFunction · 0.70
index_mapMethod · 0.45

Tested by

no test coverage detected