This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

assigning different values to u in subdomains

+1 vote

I have a rectangular domain, divided into two sub domains. I have a time dependent problem to be solved. I would like the second sub domain to act as a sponge layer, damping out the function values in this sub domain. I would like to do this manually by directly assigning in the loop $$u_1 = u$$ in sub domain 0 and $$u_1 = \mu u$$ in sub domain 1 where $$\mu \in (0,1)$$ . Can this be done, and if so, how? I've tried to give the relevant parts of my code below. Any help is greatly appreciated!

# I've defined the function spaces, trial functions,
# test functions and all that here

cf = CellFunction("size_t", mesh, 0)
o2 = AutoSubDomain(lambda x: x[0] > 1)
o2.mark(cf, 1)

# I've defined all initial conditions, functions, boundary
# conditions and the variational forms here

u = Function(V)
t = dt
while t < T+DOLFIN_EPS:
    bc.t = t
    begin("Computing at time t=%g" %g)
    b = assemble(rhs(F))
    bc.apply(A, b)
    solve(A, u.vector(), b)
    end()

    # Here, I want u1 to assign u in sub domain 0, 
    # and I want u to assign mu * u in subdomain 1 
    u1.assign(u)

    t += dt
asked Mar 4, 2014 by danieljt FEniCS Novice (410 points)

1 Answer

+3 votes
 
Best answer

Hi, here are two options that I can think of

from dolfin import *

mesh = UnitSquareMesh(100, 100)
V = FunctionSpace(mesh, 'CG', 1)

cf = CellFunction('size_t', mesh, 0)
o1 = AutoSubDomain(lambda x : x[1] >= x[0] - DOLFIN_EPS)
o1.mark(cf, 1)

mu = 100

# using dofmap
dofmap = V.dofmap()
o0_dofs = []
o1_dofs = []

for cell in cells(mesh): # compute dofs in the domains
    if cf[cell] == 0:
        o0_dofs.extend(dofmap.cell_dofs(cell.index()))
    else:
        o1_dofs.extend(dofmap.cell_dofs(cell.index()))

# unique
o0_dofs = list(set(o0_dofs))
o1_dofs = list(set(o1_dofs))

u = interpolate(Expression("x[0]*x[0]"), V)
u1 = Function(V)

u1.vector()[o0_dofs] = u.vector()[o0_dofs]
u1.vector()[o1_dofs] = mu*u.vector()[o1_dofs]

plot(u1)

#using characteristic function
v1 = Function(V)

chi0 = Function(V)
chi1 = Function(V)

for cell in cells(mesh): # set the characteristic functions
    if cf[cell] == 0:
        chi0.vector()[dofmap.cell_dofs(cell.index())] = 1
    else:
        chi1.vector()[dofmap.cell_dofs(cell.index())] = 1

v1 = project(chi0*u, V)
v1 += project(chi1*mu*u, V)

plot(v1)
interactive()
answered Mar 4, 2014 by MiroK FEniCS Expert (80,920 points)
selected Mar 5, 2014 by danieljt

Thank you again for your help Miro! It's working perfectly!

Note that the characteristic functions approach fails in parallel.

...