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

Where to apply boundary conditions in the Cahn-hilliard demo and the form of the time stepping loop for mixed functions

0 votes

Hi All,

Am using the Cahn-hilliard demo to solve a system of nonlinear pdes on mixed function space. But am not sure where to apply the Dirichlet boundary conditions. Also how should the form of my time stepping loop be? Am not sure of using the .vector() because my function space already has two vectors in it. I hope my question is clear enough.

A sample of my code is below.

The form of my functions: U, u, phi, p.

U and u are vector functions, and phi and p are scalar functions

Thank you to anyone that helps.

I have the boundary condition as list in bcs

from dolfin import *
class InitialConditions(Expression):
def eval(self, values, x):
    values[0] = x[1]
    values[1] = x[1]
    values[2] = x[1]
    values[3] = x[1]
    values[4] = 0.01
    values[5] = 0
def value_shape(self):
    return (6,)

class MyEquations(NonlinearProblem):
def __init__(self, a, L):
    NonlinearProblem.__init__(self)
    self.L = L
    self.a = a
    self.reset_sparsity = True
def F(self, b, x):
    assemble(self.L, tensor=b)
def J(self, A, x):
    assemble(self.a, tensor=A, reset_sparsity=self.reset_sparsity)
    self.reset_sparsity = False

parameters["form_compiler"]["optimize"]     = True
parameters["form_compiler"]["cpp_optimize"] = True
parameters["form_compiler"]["representation"] = "quadrature"

mesh = RectangleMesh(Point(-1,-1),Point(1,1),200,200) #Domain[-1,1]*[-1,1]

V1= VectorFunctionSpace(mesh, 'CG', degree=2)
V2=VectorFunctionSpace(mesh, 'CG', degree=2)
Q1 = FunctionSpace(mesh, 'CG', degree=1 )
Q2 = FunctionSpace(mesh, 'CG', degree=1)
VQ = MixedFunctionSpace([V1,V2, Q1, Q2])

# Define trial and test functions
duu = TrialFunctions(VQ)
m,h,q,r = TestFunctions(VQ)

 H= Function(VQ)  # Current solution
 H0 = Function(VQ)   # solution from previous converged steps


dU, du, dphi, dp = split(duu)
U, u, phi, p = split(H)
U0, u0, phi0, p0 = split(H0)


#Create initial conditions and interpolate
u_init = InitialConditions()
H.interpolate(u_init)
H0.interpolate(u_init)


#  Dirichlet boundary condition
# Sub domain for Dirichlet boundary condition
class Top(SubDomain):
     def inside(self, x, on_boundary):
         return (x[1]>1 - DOLFIN_EPS and on_boundary)

class Bottom(SubDomain):
    def inside(self, x, on_boundary):
        return (x[1]< -1 + DOLFIN_EPS and on_boundary)

 UB= Constant((-1,0))
 UT= Constant((1,0))
 ub= Constant((-1,0))
 ut= Constant((1,0))

 top= Top()
 bott = Bottom()

 bcUB= DirichletBC(VQ.sub(0), UB  ,bott)
 bcUT= DirichletBC(VQ.sub(0), UB  ,top)
 bcub= DirichletBC(VQ.sub(1), ub  ,bott )
 bcut= DirichletBC(VQ.sub(1), ub  ,top )

 bcs = [bcUB,bcUT, bcub,bcut]

 L =  L0 + L1

 # Is it ok to apply the boundary conditions here? 
 a = derivative(L,H, duu, bcs)    #  boundary conditions here? 
 problem = MyEquations(a, L)
 solver = NewtonSolver("lu")
 solver.parameters["convergence_criterion"] = "incremental"
 solver.parameters["relative_tolerance"] = 1e-6

 file = File("output.pvd", "compressed")

# Not very sure about the form here since Function space already has two vectors in it 
 # Is it right to use the .vector() here to copy H to H0 at the beginning of each time step?
#  because I have mixed function space with two vector functions and two scalar functions
T_total = 50*dt
 t=0.0
 while (t<T_total):
   t+=dt
   H0.vector()[:] = H.vector()            # Is it right to use the .vector( ) here ? 
   solver.solve(problem, H.vector())
asked Nov 20, 2015 by Vivian FEniCS Novice (550 points)
...