Beispiel #1
0
    def __init__(self, Vs):
        """
        Arguments:
            Vs = list of function spaces
        """
        Vdim = Vs[0].dim()
        Vdofmapdofs = Vs[0].dofmap().dofs()
        Vmeshsize = Vs[0].mesh().size(0)
        for V in Vs:
            assert Vdim == V.dim(), "Vs must have same dimension"
            assert (Vdofmapdofs == V.dofmap().dofs()).prod() == 1, \
            "Vs must have same dofmap"
            assert Vmeshsize == V.mesh().size(0), \
            "Vs must be built on same mesh"

        VV = createMixedFSi(Vs)

        self.SplitOperator = []
        self.AssignOperator = []
        for ii, V in enumerate(Vs):
            V_dofs = V.dofmap().dofs()
            VV_dofs = VV.sub(ii).dofmap().dofs()
            mpicomm = V.mesh().mpi_comm()
            SplitOperatorPETSc, _, _ = setupPETScmatrix(V, VV, 'aij', mpicomm)
            for jj in xrange(len(V_dofs)):
                SplitOperatorPETSc[V_dofs[jj], VV_dofs[jj]] = 1.0
            SplitOperatorPETSc.assemblyBegin()
            SplitOperatorPETSc.assemblyEnd()

            SplitOperator = dl.PETScMatrix(SplitOperatorPETSc)
            self.SplitOperator.append(SplitOperator)
            self.AssignOperator.append(Transpose(SplitOperator))
Beispiel #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
Beispiel #3
0
def testassignspliti():
    """
    Check that assign then splitting does not modify entries

    small differences recorded due to round-off error
    """
    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)
    V3 = dl.FunctionSpace(mesh, "Lagrange", 2)
    V1V2 = createMixedFSi([V1, V2, V3])
    ab = dl.Function(V1V2)
    add = dl.interpolate(dl.Constant(('-1.0', '0.0', '1.0')), V1V2)
    a, b, c = dl.Function(V1), dl.Function(V2), dl.Function(V3)
    adda, addb, addc = dl.interpolate(dl.Constant('1.0'), V1),\
    dl.interpolate(dl.Constant('1.0'), V2), dl.interpolate(dl.Constant('1.0'), V3)

    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')
        c.vector()[:] = np.random.randn(len(c.vector().array()))
        normc = c.vector().norm('l2')
        dl.assign(ab.sub(0), a)
        dl.assign(ab.sub(1), b)
        dl.assign(ab.sub(2), c)
        ab.vector().axpy(1.0, add.vector())
        ab.vector().axpy(-1.0, add.vector())
        aba, abb, abc = 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())
        c.vector().axpy(1.0, addc.vector())
        c.vector().axpy(-1.0, addc.vector())
        diffa = (a.vector() - aba.vector()).norm('l2') / norma
        diffb = (b.vector() - abb.vector()).norm('l2') / normb
        diffc = (c.vector() - abc.vector()).norm('l2') / normc
        if mpirank == 0:
            print 'diffa={} (|a|={}), diffb={} (|b|={}), diffc={} (|c|={})'.format(\
            diffa, norma, diffb, normb, diffc, normc)
Goal is to test how mixed function space behaves in Fenics
"""
from dolfin import *
import numpy as np
from fenicstools.miscfenics import createMixedFS, createMixedFSi

mpicomm = mpi_comm_world()
mpirank = MPI.rank(mpicomm)

#mpicommmesh = mpicomm
mpicommmesh = mpi_comm_self()
mesh = UnitSquareMesh(mpicommmesh, 20, 20)

V = FunctionSpace(mesh, 'CG', 1)
#VV = createMixedFS(V, V)
VV = createMixedFSi([V, V, V, V])

if mpirank == 0:
    print 'check gradient of m=(1.0,2.0,3.0,4.0)  returns 0'
m = Function(VV)
m1 = interpolate(Constant("1"), V)
m2 = interpolate(Constant("2"), V)
m3 = interpolate(Constant("3"), V)
m4 = interpolate(Constant("4"), V)
assign(m.sub(0), m1)
assign(m.sub(1), m2)
assign(m.sub(2), m3)
assign(m.sub(3), m4)
normgrad = assemble(inner(nabla_grad(m), nabla_grad(m)) * dx)
if mpirank == 0:
    print normgrad