How to apply spatially variable Dirichlet boundary condition


35
views
0
7 days ago by
Leo  
Hello
In my problem, I am solving two different equations simultaneously in a mixed space. The first equation is time-dependent and non-linear with 2 unknowns (c_1 and c_2). The second equation is linear with 2 unknowns (c_3, c_4).  Here is the minimal work:

Element1 = FiniteElement("CG", mesh.ufl_cell(), 1)
Element2 = FiniteElement("CG", submesh.ufl_cell(), 1)

# Defining the mixed function space
W_elem = MixedElement([Element1, Element1])
S_elem = MixedElement([Element2, Element2])

W = FunctionSpace(mesh, W_elem)
S = FunctionSpace(submesh, S_elem)

z = Function(W)
dz=TrialFunction(W)

c_1, c_2= split(z)
c_3, c_4 = TrialFunctions(S)

(v_1, v_2) = TestFunctions(W)
(v_3,v_4) = TestFunctions(S)

# Time variables
dt = 0.1
t = 0
T = 1.0

domains = MeshFunction('size_t', submesh, submesh.topology().dim())
dx = Measure('dx', domain=submesh, subdomain_data=domains)

boundaries = MeshFunction('size_t', submesh, submesh.topology().dim()-1)
boundaries.set_all(0)
bottom_BL.mark(boundaries, 1)
left_BL.mark(boundaries, 2)
top_BL.mark(boundaries, 3)
right_BL.mark(boundaries, 4)

u_D = Expression('a', degree = 1, a=0)
u_F = Expression('b', degree = 1,  b=0)

# Define Dirichlet boundary conditions for the c_3
bc_bottom_c_3 = DirichletBC(S.sub(0),u_D, boundaries, 1)
bc_left_c_3 = DirichletBC(S.sub(0),u_D, boundaries, 2)
bc_top_c_3 = DirichletBC(S.sub(0),u_D, boundaries, 3)
bc_right_c_3 = DirichletBC(S.sub(0),u_D, boundaries, 4)

# Define Dirichlet boundary conditions for the c_4
bc_bottom_c_3 = DirichletBC(S.sub(1),u_F, boundaries, 1)
bc_left_c_3 = DirichletBC(S.sub(1),u_F, boundaries, 2)
bc_top_c_3 = DirichletBC(S.sub(1),u_F, boundaries, 3)
bc_right_c_3 = DirichletBC(S.sub(1),u_F, boundaries, 4)

bcs_1 = ...
bcs_2 = [bc_bottom_c_3,bc_left_c_3,bc_top_c_3,bc_right_c_3,
        bc_bottom_c_4,bc_left_c_4,bc_top_c_4,bc_right_c_4]

F = ...

F2 = dot(grad(c_3), grad(v_3)) * dx +  dot(grad(c_4), grad(v_4)) * dx
a = F2
f = Constant (0.0)
L =f*v_3*dx + f*v_4*dx

k = Function(S)

while t <= T:
    J = derivative(F, z, dz)
    problem = NonlinearVariationalProblem(F, z, bcs_1, J)
    solver = NonlinearVariationalSolver(problem)

#Solving first equation
    solver.solve()
    (c_1, c_2) = z.split(True)

    u_D.a = c_1(0.5, 0.5)
    u_F.b = c_2(0.5, 0.5)

#Solving second equation
    solve(a == L, k, bcs_2)
    (c_3, c_4) = k.split(True)

    t += dt
According to the above example the calculated values of c_1 and c_2  in each time-step at the coordinate (0.5,0.5) are set as the Dirichlet boundary condition to solve the second equation to obtain c_3 and c_4.
But I do not want to use the values of c_1 and c_2 at a single coordinate as the boundary condition because these values are variable in every coordinate on the boundaries.  In other words they are dependent to the x[0] and x[1]. For the clarification please take a look at this figure:


The first equation is solved on the whole domain (red and blue) while the second equation is solved only on the red domain. As you can see for example the values of c_1 is different along the left boundary The same thing is true for the other boundaries.
In general I was wondering if there is a way to evaluate c_1 at every single coordinate on each boundary and set it as the boundary condition in every time step to solve the second equation to find the c_3 (or use c_2 as the boundary condition in the second equation to find c_4). By the end of the day I want to change this part of the code:
u_D.a = c_1(0.5, 0.5)
u_F.b = c_2(0.5, 0.5)​

To NOT use constant Dirichlet boundary conditions. Instead, I want to connect the c_1 and c_2 to the coordinates on each boundary and use spatially variable Dirichlet boundary condition.  Thanks in advance!

Community: FEniCS Project
You might use Lagrange Multipliers to set the BCs.
written 7 days ago by Moritz  
Can you provide an example? How can I implement it in my case?
written 7 days ago by Leo  
Here is the solution:

def point_i(x, on_boundary):
        tol = DOLFIN_EPS
        return (abs(x[0] - x_coordinate) < tol) and (abs(x[1] - y_coordinate) < tol)


    BC = DirichletBC(S.sub(0), c_1(x_coordinate, y_coordinate), point_i, method="pointwise")
    bcs.append(BC)​
written 4 days ago by Leo  
Please login to add an answer/comment or follow this question.

Similar posts:
Search »