예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
    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)
예제 #6
0
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)
예제 #7
0
"""
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),
예제 #8
0
            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
예제 #9
0
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))
예제 #10
0
"""
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)