def solve_state():
    a = a1 + a2 + a3 + a4 + a5
    a = replace(a, {lmb: TestFunction(V), T: TrialFunction(V)})
    l = Constant(0) * TestFunction(V) * dX
    a = assemble_multimesh(a)
    L = assemble_multimesh(l)
    bcs = [
        MultiMeshDirichletBC(V, Constant(0), mfs[0], 1, 0),
        MultiMeshDirichletBC(V, Constant(1), mfs[1], 2, 1)
    ]
    [bc.apply(a, L) for bc in bcs]
    V.lock_inactive_dofs(a, L)
    solve(a, T.vector(), L)
예제 #2
0
def project_to_background(s_top):
    # Projects a function living on the boundary intersecting with the
    # bottom mesh to the bottom mesh
    S = s_top.function_space()
    u, v = TrialFunction(S), TestFunction(S)
    a = inner(u("+"), v("+")) * dI
    A = assemble_multimesh(a)
    A.ident_zeros()
    l = inner(s_top("-"), v("+")) * dI
    L = assemble_multimesh(l)
    S.lock_inactive_dofs(A, L)
    s_back = MultiMeshFunction(S)
    solve(A, s_back.vector(), L)
    return s_back
def solve_adjoint():
    a = a1 + a2 + a3 + a4 + a5
    a = derivative(a, T, TestFunction(V))
    a = replace(a, {lmb: TrialFunction(V)})
    l = derivative(-J1, T, TestFunction(V))
    a = assemble_multimesh(a)
    L = assemble_multimesh(l)
    bcs = [
        MultiMeshDirichletBC(V, Constant(0), mfs[0], 1, 0),
        MultiMeshDirichletBC(V, Constant(0), mfs[1], 2, 1)
    ]
    [bc.apply(a, L) for bc in bcs]
    V.lock_inactive_dofs(a, L)
    solve(a, lmb.vector(), L)
예제 #4
0
 def eval_J(self):
     self.geometric_quantities()
     J_s = assemble_multimesh(inner(grad(self.u), grad(self.u)) * dX)
     J_v = self.vfac * self.Voloff**2
     J_bx = self.bfac * self.bxoff**2
     J_by = self.bfac * self.byoff**2
     self.J = float(J_s + J_v + J_bx + J_by)
예제 #5
0
 def __init_geometric_quantities(self):
     """
     Helper initializer to compute original volume and barycenter
     of the obstacle.
     """
     x = SpatialCoordinate(self.multimesh)
     V = MultiMeshFunctionSpace(self.multimesh, "CG", 1)
     x = interpolate(Expression("x[0]", degree=1), V)
     y = interpolate(Expression("x[1]", degree=1), V)
     fluid_vol = assemble_multimesh(
         Constant(1) * dx(domain=self.multimesh) +
         Constant(1) * dC(domain=self.multimesh))
     self.Vol0 = Constant(self.length_width[0] * self.length_width[1] -
                          fluid_vol)
     self.bx0 = Constant(
         (0.5 * self.length_width[0] - assemble_multimesh(x * dX)) /
         self.Vol0)
     self.by0 = Constant(
         (0.5 * self.length_width[1] - assemble_multimesh(y * dX)) /
         self.Vol0)
예제 #6
0
    def solve(self):
        """
        Solves the stokes equation with the current multimesh
        """
        (u, p) = TrialFunctions(self.VQ)
        (v, q) = TestFunctions(self.VQ)
        n = FacetNormal(self.multimesh)
        h = 2.0 * Circumradius(self.multimesh)
        alpha = Constant(6.0)

        tensor_jump = lambda u: outer(u("+"), n("+")) + outer(u("-"), n("-"))

        a_s = inner(grad(u), grad(v)) * dX
        a_IP = - inner(avg(grad(u)), tensor_jump(v))*dI\
               - inner(avg(grad(v)), tensor_jump(u))*dI\
               + alpha/avg(h) * inner(jump(u), jump(v))*dI
        a_O = inner(jump(grad(u)), jump(grad(v))) * dO

        b_s = -div(u) * q * dX - div(v) * p * dX
        b_IP = jump(u, n) * avg(q) * dI + jump(v, n) * avg(p) * dI
        l_s = inner(self.f, v) * dX

        s_C = h*h*inner(-div(grad(u)) + grad(p), -div(grad(v)) - grad(q))*dC\
              + h("+")*h("+")*inner(-div(grad(u("+"))) + grad(p("+")),
                                    -div(grad(v("+"))) + grad(q("+")))*dO
        l_C = h*h*inner(self.f, -div(grad(v)) - grad(q))*dC\
              + h("+")*h("+")*inner(self.f("+"),
                                    -div(grad(v("+"))) - grad(q("+")))*dO

        a = a_s + a_IP + a_O + b_s + b_IP + s_C
        l = l_s + l_C

        A = assemble_multimesh(a)
        L = assemble_multimesh(l)
        [bc.apply(A, L) for bc in self.bcs]
        self.VQ.lock_inactive_dofs(A, L)
        solve(A, self.w.vector(), L, "mumps")
        self.splitMMF()
예제 #7
0
 def geometric_quantities(self):
     """
     Compute volume and  barycenter of obstacle, as long as its 
     offset from original values with current multimesh
     """
     x = SpatialCoordinate(self.multimesh)
     V = MultiMeshFunctionSpace(self.multimesh, "CG", 1)
     x = interpolate(Expression("x[0]", degree=1), V)
     y = interpolate(Expression("x[1]", degree=1), V)
     fluid_vol = assemble_multimesh(
         Constant(1) * dx(domain=self.multimesh) +
         Constant(1) * dC(domain=self.multimesh))
     self.Vol = Constant(self.length_width[0] * self.length_width[1] -
                         fluid_vol)
     self.bx = Constant(
         (0.5 * self.length_width[0] - assemble_multimesh(x * dX)) /
         self.Vol)
     self.by = Constant(
         (0.5 * self.length_width[1] - assemble_multimesh(y * dX)) /
         self.Vol)
     self.Voloff = self.Vol - self.Vol0
     self.bxoff = self.bx - self.bx0
     self.byoff = self.by - self.by0
예제 #8
0
    def __init__(self,
                 V,
                 inner_product="L2",
                 map_operator=None,
                 inverse="default"):
        self.V = V

        if inner_product is not "custom":
            u = dolfin.TrialFunction(V)
            v = dolfin.TestFunction(V)

            if isinstance(V, dolfin.cpp.function.MultiMeshFunctionSpace):
                default_forms = {
                    "L2":
                    dolfin.inner(u, v) * dolfin.dX,
                    "H0_1":
                    dolfin.inner(dolfin.grad(u), dolfin.grad(v)) * dolfin.dX,
                    "H1":
                    (dolfin.inner(u, v) +
                     dolfin.inner(dolfin.grad(u), dolfin.grad(v))) * dolfin.dX,
                }
            else:
                default_forms = {
                    "L2":
                    dolfin.inner(u, v) * dolfin.dx,
                    "H0_1":
                    dolfin.inner(dolfin.grad(u), dolfin.grad(v)) * dolfin.dx,
                    "H1":
                    (dolfin.inner(u, v) +
                     dolfin.inner(dolfin.grad(u), dolfin.grad(v))) * dolfin.dx,
                }

            form = default_forms[inner_product]
            if hasattr(form.arguments()[0], "_V_multi"):
                map_operator = dolfin.assemble_multimesh(form)
            else:
                map_operator = dolfin.assemble(form)
        self.map_operator = map_operator
        if inverse in ("default", "lu"):
            self.map_solver = dolfin.LUSolver(self.map_operator)

        elif inverse == "jacobi":
            self.map_solver = dolfin.PETScKrylovSolver()
            self.map_solver.set_operator(self.map_operator)
            self.map_solver.ksp().setType("preonly")
            self.map_solver.ksp().getPC().setType("jacobi")

        elif inverse == "sor":
            self.map_solver = dolfin.PETScKrylovSolver()
            self.map_solver.set_operator(self.map_operator)
            self.map_solver.ksp().setType("preonly")
            self.map_solver.ksp().getPC().setType("sor")

        elif inverse == "amg":
            self.map_solver = dolfin.PETScKrylovSolver()
            self.map_solver.set_operator(self.map_operator)
            self.map_solver.ksp().setType("preonly")
            self.map_solver.ksp().getPC().setType("hypre")

        elif isinstance(inverse, dolfin.GenericMatrix):
            self.map_solver = dolfin.PETScKrylovSolver()
            self.map_solver.set_operators(self.map_operator, inverse)
            self.map_solver.ksp().setType("preonly")
            self.map_solver.ksp().getPC().setType("mat")

        else:
            self.map_solver = inverse
        self.solver_type = inverse
예제 #9
0
# Classic shape derivative term
da4 = tan_div(s_top("-"), n("-")) * alpha * inner(jump(T), jump(lmb)) * dI
# Material derivative of background T
da4 += alpha * inner(dot(s_top("-"), grad(T("+"))), jump(lmb)) * dI
# Material derivative of background lmb
da4 += alpha * inner(jump(T), dot(s_top("-"), grad(lmb("+")))) * dI
#-----------------------------------------------------------------------------
J1 = inner(T, T) * dX
dJ1_top = div(s_top) * inner(T, T) * dX
# Classic shape derivative term bottom mesh
dJ1_bottom = div(s_bottom) * inner(T, T) * dX
# Material derivative of background T
dJ1_bottom += 2 * inner(dot(s_bottom, grad(T)), T) * dX

J = a1 + J1 + a2 + a3 + a4
dJds = assemble_multimesh(da1_top + da1_bottom + dJ1_top + dJ1_bottom + da2 +
                          da3 + da4)

# Do a taylor test for deformation of the top mesh
Js = [assemble_multimesh(J)]
epsilons = [0.1 * 0.5**i for i in range(5)]
errors = {"0": [], "1": []}
for eps in epsilons:
    s_eps = deformation_vector()
    s_eps.vector()[:] *= eps
    for i in range(2):
        plot(multimesh.part(i))
        ALE.move(multimesh.part(i), s_eps.part(i))
        plot(multimesh.part(i), color="r")
        show()
    multimesh.build()
    multimesh.auto_cover(0, Point(1.25, 0.875))