def testblockdiagonal(): mesh = dl.UnitSquareMesh(40, 40) V1 = dl.FunctionSpace(mesh, "Lagrange", 2) test1, trial1 = dl.TestFunction(V1), dl.TrialFunction(V1) V2 = dl.FunctionSpace(mesh, "Lagrange", 2) test2, trial2 = dl.TestFunction(V2), dl.TrialFunction(V2) V1V2 = createMixedFS(V1, V2) test12, trial12 = dl.TestFunction(V1V2), dl.TrialFunction(V1V2) bd = BlockDiagonal(V1, V2, mesh.mpi_comm()) mpirank = dl.MPI.rank(mesh.mpi_comm()) if mpirank == 0: print 'mass+mass' M1 = dl.assemble(dl.inner(test1, trial1) * dl.dx) M2 = dl.assemble(dl.inner(test1, trial2) * dl.dx) M12bd = bd.assemble(M1, M2) M12 = dl.assemble(dl.inner(test12, trial12) * dl.dx) diff = M12bd - M12 nn = diff.norm('frobenius') if mpirank == 0: print '\nnn={}'.format(nn) if mpirank == 0: print 'mass+2ndD' D2 = dl.assemble( dl.inner(dl.nabla_grad(test1), dl.nabla_grad(trial2)) * dl.dx) M1D2bd = bd.assemble(M1, D2) tt1, tt2 = test12 tl1, tl2 = trial12 M1D2 = dl.assemble( dl.inner(tt1, tl1) * dl.dx + dl.inner(dl.nabla_grad(tt2), dl.nabla_grad(tl2)) * dl.dx) diff = M1D2bd - M1D2 nn = diff.norm('frobenius') if mpirank == 0: print 'nn={}'.format(nn) if mpirank == 0: print 'wM+wM' u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1) u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2) M1 = dl.assemble(dl.inner(u11 * test1, trial1) * dl.dx) M2 = dl.assemble(dl.inner(u22 * test1, trial2) * dl.dx) M12bd = bd.assemble(M1, M2) ua, ub = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"),\ degree=10), V1V2) M12 = dl.assemble( dl.inner(ua * tt1, tl1) * dl.dx + dl.inner(ub * tt2, tl2) * dl.dx) diff = M12bd - M12 nn = diff.norm('frobenius') if mpirank == 0: print 'nn={}'.format(nn)
def testsplitassign(): USEi = True mesh = dl.UnitSquareMesh(40, 40) V1 = dl.FunctionSpace(mesh, "Lagrange", 2) V2 = dl.FunctionSpace(mesh, "Lagrange", 2) if USEi: V1V2 = createMixedFSi([V1, V2]) splitassign = SplitAndAssigni([V1, V2], mesh.mpi_comm()) else: V1V2 = createMixedFS(V1, V2) splitassign = SplitAndAssign(V1, V2, mesh.mpi_comm()) mpirank = dl.MPI.rank(mesh.mpi_comm()) u = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"), degree=10), V1V2) uu = dl.Function(V1V2) u1, u2 = u.split(deepcopy=True) u1v, u2v = splitassign.split(u.vector()) u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1) u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2) a,b,c,d= dl.norm(u1.vector()-u1v), dl.norm(u2.vector()-u2v),\ dl.norm(u1.vector()-u11.vector()), dl.norm(u2.vector()-u22.vector()) if mpirank == 0: print '\nSplitting an interpolated function:', a, b, c, d if USEi: uv = splitassign.assign([u1v, u2v]) else: uv = splitassign.assign(u1v, u2v) dl.assign(uu.sub(0), u11) dl.assign(uu.sub(1), u22) a, b = dl.norm(uv - u.vector()), dl.norm(uv - uu.vector()) if mpirank == 0: print 'Putting it back together:', a, b for ii in xrange(10): u.vector()[:] = np.random.randn(len(u.vector().array())) u1, u2 = u.split(deepcopy=True) u1v, u2v = splitassign.split(u.vector()) if USEi: uv = splitassign.assign([u1v, u2v]) else: uv = splitassign.assign(u1v, u2v) a, b = dl.norm(u1.vector() - u1v), dl.norm(u2.vector() - u2v) c = dl.norm(uv - u.vector()) if mpirank == 0: print 'Splitting random numbers:', a, b print 'Putting it back together:', c
def test2(): """ Test behaviour norm in MixedFunctionSpace """ print 'TEST 2' mesh = dl.UnitSquareMesh(50, 50) V = dl.FunctionSpace(mesh, 'CG', 1) VV = createMixedFS(V, V) for ii in range(10): u = dl.interpolate(dl.Expression(\ ('sin(nn*pi*x[0])*sin(nn*pi*x[1])','0.0'),\ nn=ii+1, degree=10), VV) normn = u.vector().norm('l2') ux, uy = u.split(deepcopy=True) normux = ux.vector().norm('l2') normuy = uy.vector().norm('l2') normuxuy = np.sqrt(normux**2 + normuy**2) print 'ii={}, rel_err={}'.format(ii, np.abs(normn - normuxuy) / normn)
def test3(): """ Test behaviour inner in MixedFunctionSpace inner-product in MixedFunctionSpace not exactl the same as sum of both inner-products in underlying FunctionSpaces must be due to re-ordering in MixedFunctionSpace that creates different summation sequence in inner-product, and therefore different numerical truncation """ print 'TEST 3' mesh = dl.UnitSquareMesh(50, 50) V = dl.FunctionSpace(mesh, 'CG', 1) VV = createMixedFS(V, V) for ii in range(10): u = dl.interpolate(dl.Expression(\ ('sin(nn*pi*x[0])*sin(nn*pi*x[1])','0.0'),\ nn=ii+1, degree=10), VV) v = dl.interpolate(dl.Expression(\ ('nn*x[0]*x[1]','0.0'), nn=ii+1, degree=10), VV) #uv = u.vector().inner(v.vector()) uv = dl.as_backend_type(u.vector()).vec().dot(\ dl.as_backend_type(v.vector()).vec()) ux, uy = u.split(deepcopy=True) vx, vy = v.split(deepcopy=True) #uvx = ux.vector().inner(vx.vector()) #uvy = uy.vector().inner(vy.vector()) uvx = dl.as_backend_type(ux.vector()).vec().dot(\ dl.as_backend_type(vx.vector()).vec()) uvy = dl.as_backend_type(uy.vector()).vec().dot(\ dl.as_backend_type(vy.vector()).vec()) uvxuvy = uvx + uvy print 'ii={}, rel_err={}'.format(ii, np.abs(uv - uvxuvy) / uv)
def __init__(self, V1, V2, mpicomm): """ WARNING: MixedFunctionSpace is assumed to be V1*V2 only works if V1 and V2 are CG of same dimension """ assert V1.dim() == V2.dim(), "V1, V2 must have same dimension" assert (V1.dofmap().dofs() == V2.dofmap().dofs()).prod() == 1, \ "V1 and V2 must have same dofmap" assert V1.mesh().size(0) == V2.mesh().size(0), \ "V1, V2 must be built on same mesh" V1V2 = createMixedFS(V1, V2) SplitOperator1PETSc, _, _ = setupPETScmatrix(V1, V1V2, 'aij', mpicomm) SplitOperator2PETSc, _, _ = setupPETScmatrix(V2, V1V2, 'aij', mpicomm) V1V2_1dofs = V1V2.sub(0).dofmap().dofs() V1V2_2dofs = V1V2.sub(1).dofmap().dofs() V1dofs = V1.dofmap().dofs() V2dofs = V2.dofmap().dofs() for ii in xrange(len(V1dofs)): SplitOperator1PETSc[V1dofs[ii], V1V2_1dofs[ii]] = 1.0 for ii in xrange(len(V2dofs)): SplitOperator2PETSc[V2dofs[ii], V1V2_2dofs[ii]] = 1.0 SplitOperator1PETSc.assemblyBegin() SplitOperator1PETSc.assemblyEnd() SplitOperator2PETSc.assemblyBegin() SplitOperator2PETSc.assemblyEnd() self.SplitOperator1 = dl.PETScMatrix(SplitOperator1PETSc) self.SplitOperator2 = dl.PETScMatrix(SplitOperator2PETSc) self.AssignOperator1 = Transpose(self.SplitOperator1) self.AssignOperator2 = Transpose(self.SplitOperator2)
def testassignsplit(): """ Check that assign then splitting does not modify entries no differences recorded """ mesh = dl.UnitSquareMesh(60, 60) mpirank = dl.MPI.rank(mesh.mpi_comm()) if mpirank == 0: print '\n' V1 = dl.FunctionSpace(mesh, "Lagrange", 2) V2 = dl.FunctionSpace(mesh, "Lagrange", 2) V1V2 = createMixedFS(V1, V2) ab = dl.Function(V1V2) add = dl.interpolate(dl.Constant(('1.0', '0.0')), V1V2) a, b = dl.Function(V1), dl.Function(V2) adda, addb = dl.interpolate(dl.Constant('1.0'), V1), dl.interpolate(dl.Constant('0.0'), V2) for ii in range(10): a.vector()[:] = np.random.randn(len(a.vector().array())) norma = a.vector().norm('l2') b.vector()[:] = np.random.randn(len(b.vector().array())) normb = b.vector().norm('l2') dl.assign(ab.sub(0), a) dl.assign(ab.sub(1), b) ab.vector().axpy(1.0, add.vector()) ab.vector().axpy(-1.0, add.vector()) aba, abb = ab.split(deepcopy=True) a.vector().axpy(1.0, adda.vector()) a.vector().axpy(-1.0, adda.vector()) b.vector().axpy(1.0, addb.vector()) b.vector().axpy(-1.0, addb.vector()) diffa = (a.vector() - aba.vector()).norm('l2') / norma diffb = (b.vector() - abb.vector()).norm('l2') / normb if mpirank == 0: print 'diffa={} (|a|={}), diffb={} (|b|={})'.format(\ diffa, norma, diffb, normb)
""" Test different Krylov solver used to precondition NCG """ import dolfin as dl from fenicstools.miscfenics import createMixedFS from fenicstools.plotfenics import PlotFenics from fenicstools.jointregularization import crossgradient, normalizedcrossgradient from fenicstools.linalg.miscroutines import compute_eigfenics N = 40 mesh = dl.UnitSquareMesh(N,N) V = dl.FunctionSpace(mesh, 'CG', 1) mpirank = dl.MPI.rank(mesh.mpi_comm()) VV = createMixedFS(V, V) cg = crossgradient(VV) ncg = normalizedcrossgradient(VV) outdir = 'Output-CGvsNCG-' + str(N) + 'x' + str(N) + '/' plotfenics = PlotFenics(mesh.mpi_comm(), outdir) a1true = [ dl.interpolate(dl.Expression('log(10 - ' + '(x[0]>0.25)*(x[0]<0.75)*(x[1]>0.25)*(x[1]<0.75) * 8 )'), V), dl.interpolate(dl.Expression('log(10 - ' + '(x[0]>0.25)*(x[0]<0.75)*(x[1]>0.25)*(x[1]<0.75) * (' + '4*(x[0]<=0.5) + 8*(x[0]>0.5) ))'), V), dl.interpolate(dl.Expression('log(10 - ' + '(x[0]>0.25)*(x[0]<0.75)*(x[1]>0.25)*(x[1]<0.75) * (' + '4*(x[0]<=0.5) + 8*(x[0]>0.5) ))'), V),
checkhessabfd_med(waveobj, Mediuma, PRINT, 1e-6, [1e-5, 1e-6, 1e-7], True, 'a') else: checkhessabfd_med(waveobj, Mediuma[:1], PRINT, 1e-6, [1e-5, 1e-6, 1e-7], True, 'a') if PRINT: print 'check b-Hessian with FD' if 'b' in PARAM: checkhessabfd_med(waveobj, Mediumb, PRINT, 1e-6, [1e-5, 1e-6, 1e-7], True, 'b') else: checkhessabfd_med(waveobj, Mediumb[:1], PRINT, 1e-6, [1e-5, 1e-6, 1e-7], True, 'b') ################################################## # Solve inverse problem else: VlVl = createMixedFS(Vl, Vl) mt = dl.Function(VlVl) dl.assign(mt.sub(0), at) dl.assign(mt.sub(1), bt) m0 = dl.Function(VlVl) dl.assign(m0.sub(0), a0) dl.assign(m0.sub(1), b0) regt = waveobj.regularization.costab(at, bt) reg0 = waveobj.regularization.costab(a0, b0) if PRINT: print 'Regularization at target={:.2e}, at initial state={:.2e}'.format(\ regt, reg0) myplotf = None
def test1(): """ Test whether SingleRegularization returns same output as underlying regularization """ mesh = dl.UnitSquareMesh(40, 40) Vm = dl.FunctionSpace(mesh, 'CG', 1) VmVm = createMixedFS(Vm, Vm) ab = dl.Function(VmVm) xab = dl.Function(VmVm) x = dl.Function(Vm) regul = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) regula = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) jointregula = SingleRegularization(regula, 'a') regulb = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4}) jointregulb = SingleRegularization(regulb, 'b') for ii in range(4): #ab.vector()[:] = (ii+1.0)*np.random.randn(2*Vm.dim()) ab = dl.interpolate(dl.Expression(('sin(nn*pi*x[0])*sin(nn*pi*x[1])', 'sin(nn*pi*x[0])*sin(nn*pi*x[1])'),\ nn=ii+1, degree=10), VmVm) a, b = ab.split(deepcopy=True) print '\nTest a' costregul = regul.cost(a) costjoint = jointregula.costab(a, b) print 'cost={}, diff={}'.format(costregul, np.abs(costregul - costjoint)) gradregul = regul.grad(a) gradjoint = jointregula.gradab(a, b) xab.vector().zero() xab.vector().axpy(1.0, gradjoint) ga, gb = xab.split(deepcopy=True) gan = ga.vector().norm('l2') gbn = gb.vector().norm('l2') diffn = (gradregul - ga.vector()).norm('l2') print '|ga|={}, diff={}, |gb|={}'.format(gan, diffn, gbn) regul.assemble_hessian(a) jointregula.assemble_hessianab(a, b) Hvregul = regul.hessian(a.vector()) Hvjoint = jointregula.hessianab(a.vector(), b.vector()) xab.vector().zero() xab.vector().axpy(1.0, Hvjoint) Ha, Hb = xab.split(deepcopy=True) Han = Ha.vector().norm('l2') Hbn = Hb.vector().norm('l2') diffn = (Hvregul - Ha.vector()).norm('l2') print '|Ha|={}, diff={}, |Hb|={}'.format(Han, diffn, Hbn) solvera = regul.getprecond() solveraiter = solvera.solve(x.vector(), a.vector()) solverab = jointregula.getprecond() solverabiter = solverab.solve(xab.vector(), ab.vector()) xa, xb = xab.split(deepcopy=True) diffn = (x.vector() - xa.vector()).norm('l2') diffbn = (b.vector() - xb.vector()).norm('l2') xan = xa.vector().norm('l2') xbn = xb.vector().norm('l2') print '|xa|={}, diff={}'.format(xan, diffn) print '|xb|={}, diff={}'.format(xbn, diffbn) print 'iter={}, diff={}'.format(solveraiter, np.abs(solveraiter - solverabiter)) print 'Test b' costregul = regul.cost(b) costjoint = jointregulb.costab(a, b) print 'cost={}, diff={}'.format(costregul, np.abs(costregul - costjoint)) gradregul = regul.grad(b) gradjoint = jointregulb.gradab(a, b) xab.vector().zero() xab.vector().axpy(1.0, gradjoint) ga, gb = xab.split(deepcopy=True) gan = ga.vector().norm('l2') gbn = gb.vector().norm('l2') diffn = (gradregul - gb.vector()).norm('l2') print '|gb|={}, diff={}, |ga|={}'.format(gbn, diffn, gan) regul.assemble_hessian(b) jointregulb.assemble_hessianab(a, b) Hvregul = regul.hessian(b.vector()) Hvjoint = jointregulb.hessianab(a.vector(), b.vector()) xab.vector().zero() xab.vector().axpy(1.0, Hvjoint) Ha, Hb = xab.split(deepcopy=True) Han = Ha.vector().norm('l2') Hbn = Hb.vector().norm('l2') diffn = (Hvregul - Hb.vector()).norm('l2') print '|Hb|={}, diff={}, |Ha|={}'.format(Hbn, diffn, Han) solverb = regul.getprecond() solverbiter = solverb.solve(x.vector(), b.vector()) solverab = jointregulb.getprecond() solverabiter = solverab.solve(xab.vector(), ab.vector()) xa, xb = xab.split(deepcopy=True) diffn = (x.vector() - xb.vector()).norm('l2') diffan = (a.vector() - xa.vector()).norm('l2') xan = xa.vector().norm('l2') xbn = xb.vector().norm('l2') print '|xb|={}, diff={}'.format(xbn, diffn) print '|xa|={}, diff={}'.format(xan, diffan) print 'iter={}, diff={}'.format(solverbiter, np.abs(solverbiter - solverabiter))
""" Test how partial derivatives (dx) work in fenics """ import sys import numpy as np from dolfin import * from fenicstools.miscfenics import setfct, createMixedFS mesh = UnitSquareMesh(20,20) V = FunctionSpace(mesh, 'CG', 1) VV = createMixedFS(V, V) Vw = FunctionSpace(mesh, 'DG', 0) VwVw = createMixedFS(Vw, Vw) mpirank = MPI.rank(mesh.mpi_comm()) PRINT = (mpirank == 0) if PRINT: print 'Test 1' test = TestFunction(V) m = Function(V) for ii in range(10): m.vector()[:] = np.random.randn(m.vector().local_size()) v1 = assemble(inner(nabla_grad(test), nabla_grad(m))*dx) v1n = v1.norm('l2') v2 = assemble(inner(test.dx(0), m.dx(0))*dx + inner(test.dx(1), m.dx(1))*dx) v2n = v2.norm('l2') err = (v1-v2).norm('l2')/v1n if PRINT: print 'v1n={}, v2n={}, err={:.2e}'.format(v1n, v2n, err)