|
44 | 44 | solver.add('smoother', 'jacobi', acceptedValues=['gauss_seidel', 'chebyshev']) |
45 | 45 | solver.add('doPCoarsen', False) |
46 | 46 | solver.add('maxiter', 50) |
| 47 | +solver.add('tolerance', 0.) |
47 | 48 |
|
48 | 49 | d.declareFigure('residuals', default=False) |
| 50 | +d.declareFigure('numericalSolution') |
49 | 51 | d.declareFigure('spSolve') |
50 | 52 | d.declareFigure('spSolveError') |
51 | | -d.declareFigure('spSolveExactSolution') |
| 53 | +d.declareFigure('interpolatedAnalyticSolution') |
52 | 54 |
|
53 | 55 | params = d.process() |
54 | 56 |
|
|
95 | 97 | else: |
96 | 98 | hierarchies, connectors = paramsForMG(p.noRef, |
97 | 99 | range(d.comm.size), |
98 | | - params, p.dim, p.element) |
| 100 | + params, p.manifold_dim, p.element) |
99 | 101 | connectors['input'] = {'type': inputConnector, |
100 | 102 | 'params': {'domain': d.domain}} |
101 | 103 |
|
|
111 | 113 | overlaps = hM[FINE].multilevelAlgebraicOverlapManager |
112 | 114 | h = hM[FINE].meshLevels[-1].mesh.global_h(overlaps.comm) |
113 | 115 | hmin = hM[FINE].meshLevels[-1].mesh.global_hmin(overlaps.comm) |
114 | | - tol = {'P1': 0.5*h**2, |
115 | | - 'P2': 0.001*h**3, |
116 | | - 'P3': 0.001*h**4}[d.element] |
117 | | - tol = max(tol, 2e-9) |
| 116 | + if d.tolerance <= 0.: |
| 117 | + tol = {'P1': 0.5*h**2, |
| 118 | + 'P2': 0.001*h**3, |
| 119 | + 'P3': 0.001*h**4}[d.element] |
| 120 | + tol = max(tol, 2e-9) |
| 121 | + else: |
| 122 | + tol = d.tolerance |
118 | 123 |
|
119 | 124 | # assemble rhs on finest grid |
120 | 125 | with d.timer('Assemble rhs on finest grid'): |
|
211 | 216 | residuals = solver.residuals |
212 | 217 | A.residual_py(x, rhs, r) |
213 | 218 | resNorm = r.norm(False) |
| 219 | + numIter = max(1, numIter) |
214 | 220 | rate.add('Rate of convergence P'+label, (resNorm/r0)**(1/numIter), tested=False if label == 'BICGSTAB' else None) |
215 | 221 | its.add('Number of iterations P'+label, numIter, aTol=2 if label == 'BICGSTAB' else None) |
216 | 222 | res.add('Residual norm P'+label, resNorm) |
|
333 | 339 | # cg(b_global, u_global) |
334 | 340 | # print(cg.residuals, len(cg.residuals)) |
335 | 341 |
|
| 342 | +if p.nontrivialNullspace: |
| 343 | + const = DoFMap_fine.ones() |
| 344 | + x -= (x.inner(const)/const.inner(const))*const |
| 345 | + |
336 | 346 | if p.L2ex: |
337 | 347 | if p.boundaryCond: |
338 | 348 | d.logger.warning('L2 error is wrong for inhomogeneous BCs') |
339 | 349 | with d.timer('Mass matrix'): |
340 | 350 | M = DoFMap_fine.assembleMass(sss_format=d.symmetric) |
| 351 | + |
341 | 352 | z = DoFMap_fine.assembleRHS(p.exactSolution) |
342 | 353 | L2err = np.sqrt(np.absolute(x.inner(M*x, True, False) - |
343 | 354 | 2*z.inner(x, False, True) + |
|
379 | 390 | global_dm) = accumulate2global(subdomain, interfaces, DoFMap_fine, x, |
380 | 391 | comm=d.comm) |
381 | 392 | if d.isMaster: |
382 | | - from scipy.sparse.linalg import spsolve |
| 393 | + |
| 394 | + if d.startPlot('numericalSolution'): |
| 395 | + global_solution.plot() |
| 396 | + if p.exactSolution and d.startPlot('interpolatedAnalyticSolution'): |
| 397 | + global_dm.interpolate(p.exactSolution).plot() |
| 398 | + |
383 | 399 | from numpy.linalg import norm |
384 | 400 | A = global_dm.assembleStiffness() |
| 401 | + if p.nontrivialNullspace: |
| 402 | + from PyNucleus_base.linear_operators import Dense_LinearOperator |
| 403 | + A = A+Dense_LinearOperator(np.ones(A.shape)) |
385 | 404 | rhs = global_dm.assembleRHS(p.rhsFun) |
386 | 405 | if p.boundaryCond: |
387 | 406 | global_boundaryDoFMap = global_dm.getComplementDoFMap() |
388 | 407 | global_boundary_data = global_boundaryDoFMap.interpolate(p.boundaryCond) |
389 | 408 | global_A_boundary = global_dm.assembleStiffness(dm2=global_boundaryDoFMap) |
390 | 409 | rhs -= global_A_boundary*global_boundary_data |
391 | 410 | with d.timer('SpSolver'): |
392 | | - y = spsolve(A.to_csr(), rhs) |
| 411 | + directSolver = solverFactory('lu', A=A, setup=True) |
| 412 | + global_solution_spsolve = global_dm.zeros() |
| 413 | + directSolver(rhs, global_solution_spsolve) |
| 414 | + if p.nontrivialNullspace: |
| 415 | + const = global_dm.ones() |
| 416 | + global_solution_spsolve -= (global_solution_spsolve.inner(const)/const.inner(const))*const |
393 | 417 | if p.boundaryCond: |
394 | 418 | sol_augmented, dm_augmented = global_dm.augmentWithBoundaryData(global_solution, global_boundary_data) |
395 | 419 | global_mass = dm_augmented.assembleMass() |
|
405 | 429 | p.L2ex)) |
406 | 430 | errsSpSolve = d.addOutputGroup('errSpSolve') |
407 | 431 | errsSpSolve.add('L2', L2err) |
408 | | - errsSpSolve.add('2-norm', norm(global_solution-y, 2)) |
409 | | - errsSpSolve.add('max-norm', np.abs(global_solution-y).max()) |
| 432 | + errsSpSolve.add('2-norm', norm(global_solution-global_solution_spsolve, 2)) |
| 433 | + errsSpSolve.add('max-norm', np.abs(global_solution-global_solution_spsolve).max()) |
410 | 434 | d.logger.info('\n'+str(errsSpSolve)) |
411 | 435 | if d.startPlot('spSolve'): |
412 | 436 | import matplotlib.pyplot as plt |
413 | | - global_solution.plot() |
414 | | - if p.exactSolution and d.startPlot('spSolveExactSolution'): |
415 | | - global_dm.interpolate(p.exactSolution).plot() |
| 437 | + global_solution_spsolve.plot() |
416 | 438 | if d.startPlot('spSolveError'): |
417 | | - (global_solution-y).plot() |
| 439 | + (global_solution-global_solution_spsolve).plot() |
418 | 440 | d.finish() |
0 commit comments