|
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