def test_poisson_residual(): '''Residual for Poisson.''' ml = MeshLevel1D(j=1) prob = PsmootherPoisson(testargs) f = np.array([1.0, 0.5, 0.0, 0.5, 1.0]) w = f.copy() Fcorrect = -np.array([0.0, 0.5 * ml.h, 4.0, 0.5 * ml.h, 0.0]) assert all(prob.residual(ml, w, ml.ellf(f)) == Fcorrect)
def test_ml_cR(): '''Canonical restriction in MeshLevel1D.''' ml = MeshLevel1D(j=1) assert ml.m == 3 assert ml.mcoarser == 1 r = ml.zeros() r[1:4] = 1.0 assert all(ml.cR(r) == [0.0, 2.0, 0.0])
def test_ml_mR(): '''Monotone restriction in MeshLevel1D.''' ml = MeshLevel1D(j=2) assert ml.m == 7 v = np.array([0.0, 1.0, 1.0, 0.5, 0.5, 0.5, 0.5, 1.0, 0.0]) assert all(ml.mR(v) == [0.0, 1.0, 0.5, 1.0, 0.0]) vback = ml.cP(ml.mR(v)) # note cP uses zero boundary values assert all(vback[2:-2] >= v[2:-2]) assert all(vback[[1, -2]] == [0.5, 0.5])
def test_ml_basics(): '''Basic MeshLevel1D functionality.''' ml = MeshLevel1D(j=2) assert ml.m == 7 assert ml.l2norm(ml.zeros()) == 0.0 v = ml.zeros() assert len(v) == ml.m + 2 assert (ml.l2norm(ml.xx()) - 1.0 / np.sqrt(2.0)) < 1.0e-10 f = np.ones(ml.m + 2) ellcorrect = ml.h * np.array([0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0]) assert all(ml.ellf(f) == ellcorrect)
def test_pngssia_residual(): '''Residual for SIA.''' ml = MeshLevel1D(j=1, xmax=1800.0e3) # note [0,xmax] = [0,1800] km prob = PNsmootherSIA(testargs) ml.b = ml.zeros() # attach bed elevation to mesh m = np.array([-1.0, 0.5, 0.5, 0.5, -1.0]) / prob.secpera s = np.array([0.0, 2500.0, 3100.0, 2500.0, 0.0]) # hand-adjusted so res is small! res = prob.residual(ml, s, ml.ellf(m)) ml.checklen(res) assert all(abs(res) < 1.0e-2)
def test_poisson_pgssweep(): '''Projected Gauss-Seidel sweep for Poisson.''' ml = MeshLevel1D(j=0) prob = PsmootherPoisson(testargs) f = np.array([0.0, 1.0, 0.0]) ell = ml.ellf(f) assert all(ell == ml.h * f) w = ml.zeros() assert all(prob.residual(ml, w, ell) == -ml.h * f) phi = np.array([-2.0, -2.0, -2.0]) # thus unconstrained prob.smoothersweep(ml, w, ell, phi, forward=True) assert all(prob.residual(ml, w, ell) == ml.zeros())
def test_ml_hierarchy(): '''For an obstacle phi(x), and defect obstacles generated by monotone restriction down the hierarchy, chi_J(x) = phi(x), chi_{j-1}(x) = mR(chi_j(x)), show that the increments Phi_j(x) = chi_j(x) - chi_{j-1}(x) add up: phi(x) = sum_{j=0}^J Phi_j(x) (Interpreting this equation requires canonical prolongation.) See bottom equation on page 16 of Graeser & Kornhuber (2009).''' ml1 = MeshLevel1D(j=1) ml2 = MeshLevel1D(j=2) assert ml2.m == 7 phi = np.array([0.0, 1.0, 2.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0]) # zero b.c. assert len(phi) == ml2.m + 2 chi2 = phi chi1 = ml2.mR(chi2) chi0 = ml1.mR(chi1) assert all(chi1 == [0.0, 2.0, 1.0, 1.0, 0.0]) assert all(chi0 == [0.0, 2.0, 0.0]) Psi0 = ml2.cP(ml1.cP(chi0)) Psi1 = ml2.cP(chi1 - ml1.cP(chi0)) Psi2 = chi2 - ml2.cP(chi1) assert all(Psi0 + Psi1 + Psi2 == phi)
def test_sia_exact(): '''Exact solution for SIA.''' ml = MeshLevel1D(j=2, xmax=1800.0e3) # note [0,xmax] = [0,1800] km #ml = MeshLevel1D(j=7, xmax=1800.0e3) # note [0,xmax] = [0,1800] km prob = PNsmootherSIA(testargs) assert prob.exact_available() x = ml.xx() b = prob.phi(x) m = prob.source(x) s = prob.exact(x) assert all(b == 0.0) # check flat bed assert max(s) == prob.buelerH0 # check height assert max(x[s > 0.0]) - prob.xc < prob.buelerL # check margin pos assert min(m) < 0.0 # check mass balance assert max(m) > 0.0 # changes sign
def test_pngssia_smoothersweep(): '''Smoother for SIA.''' ml = MeshLevel1D(j=1, xmax=1800.0e3) # note [0,xmax] = [0,1800] km prob = PNsmootherSIA(testargs) ml.b = ml.zeros() # attach bed elevation to mesh ml.g = ml.zeros() # attach fixed portion of soluiton to mesh m = np.array([-1.0, 0.5, 0.5, 0.5, -1.0]) / prob.secpera s = np.array([0.0, 2500.0, 3100.0, 2500.0, 0.0]) # hand-adjusted so res is small! ell = ml.ellf(m) res = prob.residual(ml, s, ell) prob.smoothersweep(ml, s, ell, ml.b) prob.smoothersweep(ml, s, ell, ml.b) prob.smoothersweep(ml, s, ell, ml.b) newres = prob.residual(ml, s, ell) assert ml.l2norm(newres) < ml.l2norm(res)
def test_ml_injectP(): '''Prolongation of linear functionals by injection in MeshLevel1D.''' ml = MeshLevel1D(j=2) ell = np.array([0.0, 1.0, 2.0, 3.0, 0.0]) assert all( ml.injectP(ell) == [0.0, 0.0, 1.0, 0.0, 2.0, 0.0, 3.0, 0.0, 0.0])
def test_ml_iR(): '''Restriction of vectors (functions) by injection in MeshLevel1D.''' ml = MeshLevel1D(j=2) v = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 0.0]) assert all(ml.iR(v) == [0.0, 2.0, 4.0, 6.0, 0.0])
def test_ml_cP(): '''Canonical prolongation in MeshLevel1D.''' ml = MeshLevel1D(j=1) v = np.array([0.0, 1.0, 0.0]) assert all(ml.cP(v) == [0.0, 0.5, 1.0, 0.5, 0.0])
'combination of -ni and -random is not implemented') # determine correct interval L = 1.0 if args.problem == 'poisson' and args.poissoncase == 'pde2': L = 10.0 elif args.problem == 'sia': L = args.siaintervallength # hierarchy is a list of MeshLevel1D with indices [0,..,levels-1] assert args.jcoarse >= 0 assert args.J >= args.jcoarse levels = args.J - args.jcoarse + 1 hierarchy = [None] * (levels) # list [None,...,None] for j in range(levels): hierarchy[j] = MeshLevel1D(j=j + args.jcoarse, xmax=L) # set up obstacle problem with smoother (class SmootherObstacleProblem) if args.problem == 'poisson': obsprob = PsmootherPoisson(args) elif args.problem == 'plap': obsprob = PNsmootherPLap(args) elif args.problem == 'sia': obsprob = PNsmootherSIA(args) # more usage help if args.monitorerr and not obsprob.exact_available(): print( 'usage ERROR: -monitorerr but exact solution and error not available') sys.exit(5)