Esempio n. 1
0
def get_poisson_steps(pts, cells, tol):
    # Still can't initialize a mesh from points, cells
    filename = "mesh.xdmf"
    if cells.shape[1] == 3:
        meshio.write_points_cells(filename, pts, {"triangle": cells})
    else:
        assert cells.shape[1] == 4
        meshio.write_points_cells(filename, pts, {"tetra": cells})

    mesh = Mesh()
    with XDMFFile(filename) as f:
        f.read(mesh)
    os.remove(filename)
    os.remove("mesh.h5")

    # build Laplace matrix with Dirichlet boundary using dolfin
    V = FunctionSpace(mesh, "Lagrange", 1)

    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(grad(u), grad(v)) * dx
    u0 = Constant(0.0)
    bc = DirichletBC(V, u0, "on_boundary")
    f = Constant(1.0)
    L = f * v * dx

    A = assemble(a)
    b = assemble(L)
    bc.apply(A, b)

    # solve(A, x, b, "cg")
    solver = KrylovSolver("cg", "none")
    solver.parameters["absolute_tolerance"] = 0.0
    solver.parameters["relative_tolerance"] = tol

    x = Function(V)
    x_vec = x.vector()
    num_steps = solver.solve(A, x_vec, b)

    # # convert to scipy matrix
    # A = as_backend_type(A).mat()
    # ai, aj, av = A.getValuesCSR()
    # A = scipy.sparse.csr_matrix(
    #     (av, aj, ai), shape=(A.getLocalSize()[0], A.getSize()[1])
    # )

    # # ev = eigvals(A.todense())
    # ev_max = scipy.sparse.linalg.eigs(A, k=1, which="LM")[0][0]
    # assert numpy.abs(ev_max.imag) < 1.0e-15
    # ev_max = ev_max.real
    # ev_min = scipy.sparse.linalg.eigs(A, k=1, which="SM")[0][0]
    # assert numpy.abs(ev_min.imag) < 1.0e-15
    # ev_min = ev_min.real
    # cond = ev_max / ev_min

    # solve poisson system, count num steps
    # b = numpy.ones(A.shape[0])
    # out = pykry.gmres(A, b)
    # num_steps = len(out.resnorms)
    return num_steps
Esempio n. 2
0
def cyclic3D(u):
    """ Symmetrize with respect to (xyz) cycle. """
    try:
        nrm = np.linalg.norm(u.vector())
        V = u.function_space()
        assert V.mesh().topology().dim() == 3
        mesh1 = Mesh(V.mesh())
        mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]]
        W1 = FunctionSpace(mesh1, 'CG', 1)

        # testing if symmetric
        bc = DirichletBC(V, 1, DomainBoundary())
        test = Function(V)
        bc.apply(test.vector())
        test = interpolate(Function(W1, test.vector()), V)
        assert max(test.vector()) - min(test.vector()) < 1.1

        v1 = interpolate(Function(W1, u.vector()), V)

        mesh2 = Mesh(mesh1)
        mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]]
        W2 = FunctionSpace(mesh2, 'CG', 1)
        v2 = interpolate(Function(W2, u.vector()), V)
        pr = project(u+v1+v2)
        assert np.linalg.norm(pr.vector())/nrm > 0.01
        return pr
    except:
        print "Cyclic symmetrization failed!"
        return u
Esempio n. 3
0
class StreamFunction(Field):
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q)) * dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)

    def compute(self, get):
        u = get("Velocity")
        assemble(dot(u[1].dx(0) - u[0].dx(1), self.q) * dx(), tensor=self.L)
        self.bc.apply(self.L)

        self.solver.solve(self.psi.vector(), self.L)
        #solve(self.A, self.psi.vector(), self.L)

        return self.psi
Esempio n. 4
0
def assert_solves(
    mesh: Mesh,
    diffusion: Coefficient,
    convection: Optional[Coefficient],
    reaction: Optional[Coefficient],
    source: Coefficient,
    exact: Coefficient,
    l2_tol: Optional[float] = 1.0e-8,
    h1_tol: Optional[float] = 1.0e-6,
):
    eafe_matrix = eafe_assemble(mesh, diffusion, convection, reaction)

    pw_linears = FunctionSpace(mesh, "Lagrange", 1)
    test_function = TestFunction(pw_linears)
    rhs_vector = assemble(source * test_function * dx)

    bc = DirichletBC(pw_linears, exact, lambda _, on_bndry: on_bndry)
    bc.apply(eafe_matrix, rhs_vector)

    solution = Function(pw_linears)
    solver = LUSolver(eafe_matrix, "default")
    solver.parameters["symmetric"] = False
    solver.solve(solution.vector(), rhs_vector)

    l2_err: float = errornorm(exact, solution, "l2", 3)
    assert l2_err <= l2_tol, f"L2 error too large: {l2_err} > {l2_tol}"

    h1_err: float = errornorm(exact, solution, "H1", 3)
    assert h1_err <= h1_tol, f"H1 error too large: {h1_err} > {h1_tol}"
Esempio n. 5
0
def compute_error(problem, mesh_size):
    mesh = problem.mesh_generator(mesh_size)

    u = problem.solution['u']
    u_sol = Expression((ccode(u['value'][0]), ccode(u['value'][1])),
                       degree=u['degree'])

    p = problem.solution['p']
    p_sol = Expression(ccode(p['value']), degree=p['degree'])

    f = Expression(
        (ccode(problem.f['value'][0]), ccode(problem.f['value'][1])),
        degree=problem.f['degree'])

    W = VectorElement('Lagrange', mesh.ufl_cell(), 2)
    P = FiniteElement('Lagrange', mesh.ufl_cell(), 1)
    WP = FunctionSpace(mesh, W * P)

    # Get Dirichlet boundary conditions
    u_bcs = DirichletBC(WP.sub(0), u_sol, 'on_boundary')
    p_bcs = DirichletBC(WP.sub(1), p_sol, 'on_boundary')

    u_approx, p_approx = flow.stokes.solve(WP,
                                           bcs=[u_bcs, p_bcs],
                                           mu=problem.mu,
                                           f=f,
                                           verbose=True,
                                           tol=1.0e-12)

    # compute errors
    u_error = errornorm(u_sol, u_approx)
    p_error = errornorm(p_sol, p_approx)
    return mesh.hmax(), u_error, p_error
Esempio n. 6
0
    def transfer(self, V):

        fenics_bcs = list()

        for bc in self._bcs:
            if bc.component is not None:
                if not bc.pointwise:
                    fenics_bcs.append(
                        DirichletBC(V.sub(bc.component), bc.expression,
                                    bc.domain))
                else:
                    fenics_bcs.append(
                        DirichletBC(V.sub(bc.component),
                                    bc.expression,
                                    bc.domain,
                                    method='pointwise'))
            else:
                if not bc.pointwise:
                    fenics_bcs.append(DirichletBC(V, bc.expression, bc.domain))
                else:
                    fenics_bcs.append(
                        DirichletBC(V,
                                    bc.expression,
                                    bc.domain,
                                    method='pointwise'))

        return fenics_bcs
Esempio n. 7
0
def homogenize(bcs):
    b = []
    for bc in bcs:
        b0 = DirichletBC(bc)
        b0.homogenize()
        b.append(b0)
    return b
Esempio n. 8
0
  def __init__(self, coarse_mesh, nref, p_coarse, p_fine):
    super(LaplaceEigenvalueProblem, self).__init__(coarse_mesh, nref, p_coarse, p_fine)

    print0("Assembling fine-mesh problem")

    self.dirichlet_bdry = lambda x,on_boundary: on_boundary

    bc = DirichletBC(self.V_fine, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_fine)
    v = TestFunction(self.V_fine)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix.
    b = v*dx # just need this to feed an argument to assemble_system
    assemble_system(a, b, bc, A_tensor=self.A_fine)
    assemble_system(m, b, bc, A_tensor=self.B_fine)
    # set the diagonal elements of M corresponding to boundary nodes to zero to
    # remove spurious eigenvalues.
    bc.zero(self.B_fine)

    print0("Assembling coarse-mesh problem")

    self.bc_coarse = DirichletBC(self.V_coarse, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_coarse)
    v = TestFunction(self.V_coarse)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix, without Dirichlet BCs. Dirichlet DOFs will be removed later.
    assemble(a, tensor=self.A_coarse)
    assemble(m, tensor=self.B_coarse)
Esempio n. 9
0
    def stokes(self):
        P2 = VectorElement("CG", self.mesh.ufl_cell(), 2)
        P1 = FiniteElement("CG", self.mesh.ufl_cell(), 1)
        TH = P2 * P1
        VQ = FunctionSpace(self.mesh, TH)
        mf = self.mf
        self.no_slip = Constant((0., 0))
        self.topflow = Expression(("-x[0] * (x[0] - 1.0) * 6.0 * m", "0.0"),
                                  m=self.U_m,
                                  degree=2)
        bc0 = DirichletBC(VQ.sub(0), self.topflow, mf, self.bc_dict["top"])
        bc1 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["left"])
        bc2 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["bottom"])
        bc3 = DirichletBC(VQ.sub(0), self.no_slip, mf, self.bc_dict["right"])
        # bc4 = DirichletBC(VQ.sub(1), Constant(0), mf, self.bc_dict["top"])
        bcs = [bc0, bc1, bc2, bc3]

        vup = TestFunction(VQ)
        up = TrialFunction(VQ)
        # the solution will be in here:
        up_ = Function(VQ)

        u, p = split(up)  # Trial
        vu, vp = split(vup)  # Test
        u_, p_ = split(up_)  # Function holding the solution
        F = self.mu*inner(grad(vu), grad(u))*dx - inner(div(vu), p)*dx \
            - inner(vp, div(u))*dx + dot(self.g*self.rho, vu)*dx
        solve(lhs(F) == rhs(F), up_, bcs=bcs)
        self.u_.assign(project(u_, self.V))
        self.p_.assign(project(p_, self.Q))
        return
Esempio n. 10
0
def homogenize(bcs):
    b = []
    for bc in bcs:
        b0 = DirichletBC(bc)
        b0.homogenize()
        b.append(b0)
    return b
Esempio n. 11
0
    def __init__(self, U_m, mesh):
        """Function spaces and BCs"""
        V = VectorFunctionSpace(mesh, 'P', 2)
        Q = FunctionSpace(mesh, 'P', 1)
        self.mesh = mesh
        self.vu, self.vp = TestFunction(V), TestFunction(Q)  # for integration
        self.u_, self.p_ = Function(V), Function(Q)  # for the solution
        self.u_1, self.p_1 = Function(V), Function(Q)  # for the prev. solution
        self.u_k, self.p_k = Function(V), Function(Q)  # for the prev. solution
        self.u, self.p = TrialFunction(V), TrialFunction(Q)  # unknown!

        U0_str = "4.*U_m*x[1]*(.41-x[1])/(.41*.41)"
        x = [0,
             .41 / 2]  # evaluate the Expression at the center of the channel
        self.U_mean = np.mean(2 / 3 * eval(U0_str))

        U0 = Expression((U0_str, "0"), U_m=U_m, degree=2)
        bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
        bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
        bc2 = DirichletBC(V, U0, inlet)
        bc3 = DirichletBC(Q, Constant(0), outlet)
        self.bcu = [bc0, bc1, bc2]
        self.bcp = [bc3]
        # ds is needed to compute drag and lift.
        ASD1 = AutoSubDomain(topandbottom)
        ASD2 = AutoSubDomain(cylinderwall)
        mf = MeshFunction("size_t", mesh, 1)
        mf.set_all(0)
        ASD1.mark(mf, 1)
        ASD2.mark(mf, 2)
        self.ds_ = ds(subdomain_data=mf, domain=mesh)
        return
Esempio n. 12
0
def cyclic3D(u):
    """ Symmetrize with respect to (xyz) cycle. """
    try:
        nrm = np.linalg.norm(u.vector())
        V = u.function_space()
        assert V.mesh().topology().dim() == 3
        mesh1 = Mesh(V.mesh())
        mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]]
        W1 = FunctionSpace(mesh1, 'CG', 1)

        # testing if symmetric
        bc = DirichletBC(V, 1, DomainBoundary())
        test = Function(V)
        bc.apply(test.vector())
        test = interpolate(Function(W1, test.vector()), V)
        assert max(test.vector()) - min(test.vector()) < 1.1

        v1 = interpolate(Function(W1, u.vector()), V)

        mesh2 = Mesh(mesh1)
        mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]]
        W2 = FunctionSpace(mesh2, 'CG', 1)
        v2 = interpolate(Function(W2, u.vector()), V)
        pr = project(u + v1 + v2)
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        print "Cyclic symmetrization failed!"
        return u
Esempio n. 13
0
class StreamFunction(Field):
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q))*dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)


    def compute(self, get):
        u = get("Velocity")
        assemble(dot(u[1].dx(0)-u[0].dx(1), self.q)*dx(), tensor=self.L)
        self.bc.apply(self.L)

        self.solver.solve(self.psi.vector(), self.L)
        #solve(self.A, self.psi.vector(), self.L)

        return self.psi
Esempio n. 14
0
    class Heat(object):
        '''
        u' = \\Delta u + f
        '''
        def __init__(self, V):
            self.sol = Expression(sympy.printing.ccode(solution),
                                  degree=MAX_DEGREE,
                                  t=0.0,
                                  cell=triangle)

            self.V = V
            u = TrialFunction(V)
            v = TestFunction(V)
            self.M = assemble(u * v * dx)

            n = FacetNormal(self.V.mesh())
            self.A = assemble(-inner(kappa * grad(u), grad(v /
                                                           (rho * cp))) * dx +
                              inner(kappa * grad(u), n) * v / (rho * cp) * ds)

            self.bcs = DirichletBC(self.V, self.sol, 'on_boundary')
            return

        def eval_alpha_M_beta_F(self, alpha, beta, u, t):
            # Evaluate  alpha * M * u + beta * F(u, t).
            uvec = u.vector()

            v = TestFunction(self.V)
            f.t = t
            b = assemble(f * v / (rho * cp) * dx)

            out = Function(self.V)
            out.vector()[:] = \
                alpha * (self.M * uvec) + beta * (self.A * uvec + b)
            return out

        def solve_alpha_M_beta_F(self, alpha, beta, b, t):
            # Solve  alpha * M * u + beta * F(u, t) = b  for u.
            A = alpha * self.M + beta * self.A

            f.t = t
            v = TestFunction(self.V)
            b2 = f / (rho * cp)

            rhs = assemble((b - beta * b2) * v * dx)
            self.bcs.apply(A, rhs)

            solver = \
                KrylovSolver('gmres', 'ilu') if alpha < 0.0 or beta > 0.0 \
                else KrylovSolver('cg', 'amg')
            solver.parameters['relative_tolerance'] = 1.0e-13
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = False
            solver.set_operator(A)

            u = Function(self.V)
            solver.solve(u.vector(), rhs)
            return u
Esempio n. 15
0
 def __init__(self):
     self.mesh = UnitSquareMesh(40, 40, "left/right")
     self.V = FunctionSpace(self.mesh, "Lagrange", 1)
     self.bc = DirichletBC(self.V, 0.0, "on_boundary")
     u = TrialFunction(self.V)
     v = TestFunction(self.V)
     self.a = assemble(dot(grad(u), grad(v)) * dx)
     self.m = assemble(u * v * dx)
Esempio n. 16
0
 def __init__(self, V):
     self.V = V
     u = TrialFunction(V)
     v = TestFunction(V)
     self.M = assemble(u * v * dx)
     self.A = assemble(-dot(grad(u), grad(v)) * dx)
     self.b = assemble(1.0 * v * dx)
     self.bcs = DirichletBC(self.V, 0.0, 'on_boundary')
     return
Esempio n. 17
0
def ball_in_tube():
    mesh = Mesh("../meshes/2d/ball-in-tube-cylindrical-coarse4.xml")
    V0 = FunctionSpace(mesh, "CG", 2)
    V1 = FunctionSpace(mesh, "B", 3)
    V = V0 + V1
    W = MixedFunctionSpace([V, V])

    P = FunctionSpace(mesh, "CG", 1)

    # Define mesh and boundaries.
    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] < GMSH_EPS

    left_boundary = LeftBoundary()

    class RightBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] > 1.0 - GMSH_EPS

    right_boundary = RightBoundary()

    class LowerBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] < GMSH_EPS

    lower_boundary = LowerBoundary()

    class UpperBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] > 5.0 - GMSH_EPS

    class CoilBoundary(SubDomain):
        def inside(self, x, on_boundary):
            # One has to pay a little bit of attention when defining the
            # coil boundary; it's easy to miss the edges closest to x[0]=0.
            return (
                on_boundary
                and x[1] > 1.0 - GMSH_EPS
                and x[1] < 2.0 + GMSH_EPS
                and x[0] < 1.0 - GMSH_EPS
            )

    coil_boundary = CoilBoundary()

    u_bcs = [
        DirichletBC(W, (0.0, 0.0), right_boundary),
        DirichletBC(W.sub(0), 0.0, left_boundary),
        DirichletBC(W, (0.0, 0.0), lower_boundary),
        DirichletBC(W, (0.0, 0.0), coil_boundary),
    ]
    p_bcs = []
    # p_bcs = [DirichletBC(Q, 0.0, upper_boundary)]
    return mesh, W, P, u_bcs, p_bcs
Esempio n. 18
0
def pinBC(membrane):
    bc = []
    if membrane.nsd==2:
        bc.append(DirichletBC(membrane.V, Constant((0,0)), bd_all_1D))

    elif membrane.nsd==3:
        # This constrains the thickness at the support but is not plane strain
        bc.append(DirichletBC(membrane.V.sub(1), Constant(0), bd_all))
        bc.append(DirichletBC(membrane.V, Constant((0, 0, 0)), bd_x))

    return bc
Esempio n. 19
0
 def get_boundary_conditions(self, use_pressure_BC, v_space, p_space):
     # boundary parts: 1 walls, 2 inflow, 3 outflow
     bc0 = DirichletBC(v_space, (0.0, 0.0, 0.0), self.facet_function,
                       1)  # no-slip
     inflow = DirichletBC(v_space, self.v_in, self.facet_function, 2)
     bcu = [inflow, bc0]
     bcp = []
     if use_pressure_BC:
         outflow = DirichletBC(p_space, 0.0, self.facet_function, 3)
         bcp = [outflow]
     return bcu, bcp
Esempio n. 20
0
def create_dirichlet_conditions(values, boundaries, function_spaces):
    """Create Dirichlet boundary conditions for given boundary values,
    boundaries and function space."""

    # Check that the size matches
    if len(values) != len(boundaries):
        error(
            "The number of Dirichlet values does not match the number of Dirichlet boundaries."
        )
    if len(values) != len(function_spaces):
        error(
            "The number of Dirichlet values does not match the number of function spaces."
        )
    if len(boundaries) != len(function_spaces):
        error(
            "The number of Dirichlet boundaries  does not match the number of function spaces."
        )

    info("Creating %d Dirichlet boundary condition(s)." % len(values))

    # Create Dirichlet conditions
    bcs = []
    for (i, value) in enumerate(values):

        # Get current boundary
        boundary = boundaries[i]
        function_space = function_spaces[i]

        # Case 0: boundary is a string
        if isinstance(boundary, str):
            boundary = CompiledSubDomain(boundary)
            bc = DirichletBC(function_space, value, boundary)

        # Case 1: boundary is a SubDomain
        elif isinstance(boundary, SubDomain):
            bc = DirichletBC(function_space, value, boundary)

        # Case 2: boundary is defined by a MeshFunction

        elif isinstance(boundary, tuple):
            mesh_function, index = boundary
            bc = DirichletBC(function_space, value, mesh_function, index)

        # Unhandled case
        else:
            error(
                "Unhandled boundary specification for boundary condition. "
                "Expecting a string, a SubDomain or a (MeshFunction, int) tuple."
            )

        bcs.append(bc)

    return bcs
Esempio n. 21
0
 def get_boundary_conditions(self, use_pressure_BC, v_space, p_space):
     # boundary parts: 1 walls, 2, 4 inflow, 3, 5 outflow
     # Boundary conditions
     bc_wall = DirichletBC(v_space, (0.0, 0.0, 0.0), self.facet_function, 1)
     bc_cyl = DirichletBC(v_space, (0.0, 0.0, 0.0), self.facet_function, 5)
     inflow = DirichletBC(v_space, self.v_in, self.facet_function, 2)
     bcu = [inflow, bc_cyl, bc_wall]
     bcp = []
     if use_pressure_BC:
         outflow = DirichletBC(p_space, 0.0, self.facet_function, 3)
         bcp = [outflow]
     return bcu, bcp
Esempio n. 22
0
def navier_stokes_IPCS(mesh, dt, parameter):
    """
    fenics code: weak form of the problem.
    """
    mu, rho, nu = parameter
    V = VectorFunctionSpace(mesh, 'P', 2)
    Q = FunctionSpace(mesh, 'P', 1)

    bc0 = DirichletBC(V, Constant((0, 0)), cylinderwall)
    bc1 = DirichletBC(V, Constant((0, 0)), topandbottom)
    bc2 = DirichletBC(V, U0, inlet)
    bc3 = DirichletBC(Q, Constant(1), outlet)
    bcs = [bc0, bc1, bc2, bc3]

    # ds is needed to compute drag and lift. Not used here.
    ASD1 = AutoSubDomain(topandbottom)
    ASD2 = AutoSubDomain(cylinderwall)
    mf = MeshFunction("size_t", mesh, 1)
    mf.set_all(0)
    ASD1.mark(mf, 1)
    ASD2.mark(mf, 2)
    ds_ = ds(subdomain_data=mf, domain=mesh)

    vu, vp = TestFunction(V), TestFunction(Q)  # for integration
    u_, p_ = Function(V), Function(Q)  # for the solution
    u_1, p_1 = Function(V), Function(Q)  # for the prev. solution
    u, p = TrialFunction(V), TrialFunction(Q)  # unknown!
    bcu = [bcs[0], bcs[1], bcs[2]]
    bcp = [bcs[3]]

    n = FacetNormal(mesh)
    u_mid = (u + u_1) / 2.0
    F1 = rho*dot((u - u_1) / dt, vu)*dx \
        + rho*dot(dot(u_1, nabla_grad(u_1)), vu)*dx \
        + inner(sigma(u_mid, p_1, mu), epsilon(vu))*dx \
        + dot(p_1*n, vu)*ds - dot(mu*nabla_grad(u_mid)*n, vu)*ds
    a1 = lhs(F1)
    L1 = rhs(F1)
    # Define variational problem for step 2
    a2 = dot(nabla_grad(p), nabla_grad(vp)) * dx
    L2 = dot(nabla_grad(p_1), nabla_grad(vp)) * dx - (
        rho / dt) * div(u_) * vp * dx  # rho missing in FEniCS tutorial
    # Define variational problem for step 3
    a3 = dot(u, vu) * dx
    L3 = dot(u_, vu) * dx - dt * dot(nabla_grad(p_ - p_1), vu) * dx
    # Assemble matrices
    A1 = assemble(a1)
    A2 = assemble(a2)
    A3 = assemble(a3)
    # Apply boundary conditions to matrices
    [bc.apply(A1) for bc in bcu]
    [bc.apply(A2) for bc in bcp]
    return u_, p_, u_1, p_1, L1, A1, L2, A2, L3, A3, bcu, bcp
Esempio n. 23
0
        def __init__(self, V):
            self.sol = Expression(sympy.printing.ccode(theta),
                                  degree=MAX_DEGREE,
                                  t=0.0,
                                  cell=triangle)

            self.V = V
            u = TrialFunction(V)
            v = TestFunction(V)
            self.M = assemble(u * v * dx)
            self.A = assemble(-inner(grad(u), grad(v)) * dx)
            self.bcs = DirichletBC(self.V, self.sol, 'on_boundary')
            return
Esempio n. 24
0
def rollerBC(membrane):
    bc =[]
    if membrane.nsd==2:
        # 
        bc.append(DirichletBC(membrane.V.sub(1), Constant(0), bd_all_1D))
        bc.append(DirichletBC(membrane.V.sub(0), Constant(0), bd_x_mid_1D))

    elif membrane.nsd==3:
        # This constrains the thickness at the support but is not plane strain
        bc.append(DirichletBC(membrane.V.sub(1), Constant(0), bd_all))  
        bc.append(DirichletBC(membrane.V.sub(0), Constant(0), bd_x_mid))
        bc.append(DirichletBC(membrane.V.sub(2), Constant(0), bd_x))
    return bc
Esempio n. 25
0
    def define_boundary_conditions(self):
        V = self.z.function_space()

        bc_clamped = [
            DirichletBC(V.sub(1), Constant([0., 0.]), 'on_boundary'),
            DirichletBC(V.sub(2), Constant(0.), 'on_boundary')
        ]
        bc_free = []
        bc_vert = [DirichletBC(V.sub(2), Constant(0.), 'on_boundary')]
        bc_horiz = [DirichletBC(V.sub(1), Constant([0., 0.]), 'on_boundary')]

        bcs = [bc_clamped, bc_free, bc_vert, bc_horiz]
        return bcs[self.bc_no]
Esempio n. 26
0
    class Bratu(object):
        def __init__(self):
            self.mesh = UnitSquareMesh(40, 40, "left/right")

            self.V = FunctionSpace(self.mesh, "Lagrange", 1)

            self.bc = DirichletBC(self.V, 0.0, "on_boundary")

            u = TrialFunction(self.V)
            v = TestFunction(self.V)
            self.a = assemble(dot(grad(u), grad(v)) * dx)
            self.m = assemble(u * v * dx)

        def inner(self, a, b):
            return a.inner(self.m * b)

        def norm2_r(self, a):
            return a.inner(a)

        def f(self, u, lmbda):
            v = TestFunction(self.V)
            ufun = Function(self.V)
            ufun.vector()[:] = u
            out = self.a * u - lmbda * assemble(exp(ufun) * v * dx)
            DirichletBC(self.V, ufun, "on_boundary").apply(out)
            return out

        def df_dlmbda(self, u, lmbda):
            v = TestFunction(self.V)
            ufun = Function(self.V)
            ufun.vector()[:] = u
            out = -assemble(exp(ufun) * v * dx)
            self.bc.apply(out)
            return out

        def jacobian_solver(self, u, lmbda, rhs):
            t = TrialFunction(self.V)
            v = TestFunction(self.V)
            # from dolfin import Constant
            # a = assemble(
            #     dot(grad(t), grad(v)) * dx - Constant(lmbda) * exp(u) * t * v * dx
            # )
            ufun = Function(self.V)
            ufun.vector()[:] = u
            a = self.a - lmbda * assemble(exp(ufun) * t * v * dx)
            self.bc.apply(a)
            x = Function(self.V)
            # solve(a, x.vector(), rhs, "gmres", "ilu")
            solve(a, x.vector(), rhs)
            return x.vector()
Esempio n. 27
0
def symmetrize(u, d, sym):
    """ Symmetrize function u. """
    if len(d) == 3:
        # three dimensions -> cycle XYZ
        return cyclic3D(u)
    elif len(d) >= 4:
        # four dimensions -> rotations in 2D
        return rotational(u, d[-1])
    nrm = np.linalg.norm(u.vector())
    V = u.function_space()
    mesh = Mesh(V.mesh())

    # test if domain is symmetric using function equal 0 inside, 1 on boundary
    # extrapolation will force large values if not symmetric since the flipped
    # domain is different
    bc = DirichletBC(V, 1, DomainBoundary())
    test = Function(V)
    bc.apply(test.vector())

    if len(d) == 2:
        # two dimensions given: swap dimensions
        mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]]
    else:
        # one dimension given: reflect
        mesh.coordinates()[:, d[0]] *= -1
    # FIXME functionspace takes a long time to construct, maybe copy?
    W = FunctionSpace(mesh, 'CG', 1)
    try:
        # testing
        test = interpolate(Function(W, test.vector()), V)
        # max-min should be around 1 if domain was symmetric
        # may be slightly above due to boundary approximation
        assert max(test.vector()) - min(test.vector()) < 1.1

        v = interpolate(Function(W, u.vector()), V)
        if sym:
            # symmetric
            pr = project(u+v)
        else:
            # antisymmetric
            pr = project(u-v)
        # small solution norm most likely means that symmetrization gives
        # trivial function
        assert np.linalg.norm(pr.vector())/nrm > 0.01
        return pr
    except:
        # symmetrization failed for some reason
        print "Symmetrization " + str(d) + " failed!"
        return u
Esempio n. 28
0
def symmetrize(u, d, sym):
    """ Symmetrize function u. """
    if len(d) == 3:
        # three dimensions -> cycle XYZ
        return cyclic3D(u)
    elif len(d) >= 4:
        # four dimensions -> rotations in 2D
        return rotational(u, d[-1])
    nrm = np.linalg.norm(u.vector())
    V = u.function_space()
    mesh = Mesh(V.mesh())

    # test if domain is symmetric using function equal 0 inside, 1 on boundary
    # extrapolation will force large values if not symmetric since the flipped
    # domain is different
    bc = DirichletBC(V, 1, DomainBoundary())
    test = Function(V)
    bc.apply(test.vector())

    if len(d) == 2:
        # two dimensions given: swap dimensions
        mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]]
    else:
        # one dimension given: reflect
        mesh.coordinates()[:, d[0]] *= -1
    # FIXME functionspace takes a long time to construct, maybe copy?
    W = FunctionSpace(mesh, 'CG', 1)
    try:
        # testing
        test = interpolate(Function(W, test.vector()), V)
        # max-min should be around 1 if domain was symmetric
        # may be slightly above due to boundary approximation
        assert max(test.vector()) - min(test.vector()) < 1.1

        v = interpolate(Function(W, u.vector()), V)
        if sym:
            # symmetric
            pr = project(u + v)
        else:
            # antisymmetric
            pr = project(u - v)
        # small solution norm most likely means that symmetrization gives
        # trivial function
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        # symmetrization failed for some reason
        print "Symmetrization " + str(d) + " failed!"
        return u
Esempio n. 29
0
def dbcs_to_productspace(W, bcs_list):
    new_bcs = []
    for k, bcs in enumerate(bcs_list):
        for bc in bcs:
            C = bc.function_space().component()
            # pylint: disable=len-as-condition
            if len(C) == 0:
                new_bcs.append(DirichletBC(W.sub(k), bc.value(), bc.domain_args[0]))
            else:
                assert len(C) == 1, "Illegal number of subspace components."
                new_bcs.append(
                    DirichletBC(W.sub(k).sub(int(C[0])), bc.value(), bc.domain_args[0])
                )

    return new_bcs
Esempio n. 30
0
    def solve(self, L, a, plate_potential):
        A = assemble(a)
        b = assemble(L)
        # print(' assembled')

        dirichlet_bc = DirichletBC(self.V, plate_potential,
                                   (lambda x, on_boundary: on_boundary and x[2]
                                    < self.GROUNDED_PLATE_AT))

        dirichlet_bc.apply(A, b)
        # print(' modified')
        f = self.function()
        self.solver.solve(A, f.vector(), b)
        # print(' solved')
        return f
Esempio n. 31
0
def cavity():
    # Define mesh and boundaries.
    mesh = UnitSquareMesh(32, 32, "left/right")

    V = VectorFunctionSpace(mesh, "CG", 2)
    Q = FunctionSpace(mesh, "CG", 1)

    class LeftBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] < GMSH_EPS

    left_boundary = LeftBoundary()

    class RightBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0] > 1.0 - GMSH_EPS

    right_boundary = RightBoundary()

    class LowerBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] < GMSH_EPS

    lower_boundary = LowerBoundary()

    class UpperBoundary(SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[1] > 1.0 - GMSH_EPS

    upper_boundary = UpperBoundary()

    # Boundary conditions for the velocity.
    u_bcs = [
        DirichletBC(V, (0.0, 0.0), lower_boundary),
        DirichletBC(V, (0.0, 0.0), upper_boundary),
        DirichletBC(V, (0.0, 0.0), right_boundary),
        DirichletBC(V, (0.0, 0.0), left_boundary),
    ]
    p_bcs = []
    return (
        mesh,
        V,
        Q,
        u_bcs,
        p_bcs,
        [right_boundary],
        [upper_boundary, left_boundary, lower_boundary],
    )
Esempio n. 32
0
def les_setup(u_, mesh, KineticEnergySGS, assemble_matrix, CG1Function,
              nut_krylov_solver, bcs, **NS_namespace):
    """
    Set up for solving the Kinetic Energy SGS-model.
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    dim = mesh.geometry().dim()
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG) * dx))
    delta.vector().set_local(delta.vector().array()**(1. / dim))
    delta.vector().apply('insert')

    Ck = KineticEnergySGS["Ck"]
    ksgs = interpolate(Constant(1E-7), CG1)
    bc_ksgs = DirichletBC(CG1, 0, "on_boundary")
    A_mass = assemble_matrix(TrialFunction(CG1) * TestFunction(CG1) * dx)
    nut_form = Ck * delta * sqrt(ksgs)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")
    At = Matrix()
    bt = Vector(nut_.vector())
    ksgs_sol = KrylovSolver("bicgstab", "additive_schwarz")
    #ksgs_sol.parameters["preconditioner"]["structure"] = "same_nonzero_pattern"
    ksgs_sol.parameters["error_on_nonconvergence"] = False
    ksgs_sol.parameters["monitor_convergence"] = False
    ksgs_sol.parameters["report"] = False
    del NS_namespace
    return locals()
Esempio n. 33
0
 def f(self, u, lmbda):
     v = TestFunction(self.V)
     ufun = Function(self.V)
     ufun.vector()[:] = u
     out = self.a * u - lmbda * assemble(exp(ufun) * v * dx)
     DirichletBC(self.V, ufun, "on_boundary").apply(out)
     return out
Esempio n. 34
0
    def test_cmscr1d_weak_solution_zero_Dirichlet(self):
        print("Running test 'test_cmscr1d_weak_solution_zero_Dirichlet'")
        # Define temporal and spatial sample points.
        m, n = 10, 20

        # Define mesh and function space.
        mesh = UnitSquareMesh(m - 1, n - 1)
        V = dh.create_function_space(mesh, 'default')
        W = dh.create_vector_function_space(mesh, 'default')

        # Define boundary conditions for velocity.
        bc = DirichletBC(W.sub(0), Constant(0), dh.DirichletBoundary())

        # Create zero function.
        f = Function(V)

        # Compute velocity.
        v, k, res, fun, converged = cmscr1d_weak_solution(W, f,
                                                          f.dx(0), f.dx(1),
                                                          1.0, 1.0,
                                                          1.0, 1.0, 1.0,
                                                          bcs=bc)
        v = v.vector().get_local()
        k = k.vector().get_local()

        np.testing.assert_allclose(v.shape, m * n)
        np.testing.assert_allclose(v, np.zeros_like(v))
        np.testing.assert_allclose(k.shape, m * n)
        np.testing.assert_allclose(k, np.zeros_like(k))
Esempio n. 35
0
 def _boundary_condition(self, *args, **kwargs):
     return DirichletBC(
         self._V,
         Constant(
             self.potential_behind_dome(self.RADIUS, *args,
                                        **kwargs)),
         self._boundaries, self.EXTERNAL_SURFACE)
# this option does not appear to be working at the moment:
#parameters["num_threads"] = 6 
mycomm = mpi_comm_world()
myrank = MPI.rank(mycomm)

# Domain, f-e spaces and boundary conditions:
mesh = UnitSquareMesh(500,500)
V = FunctionSpace(mesh, 'Lagrange', 2)  # space for state and adjoint variables
Vm = FunctionSpace(mesh, 'Lagrange', 1) # space for medium parameter
Vme = FunctionSpace(mesh, 'Lagrange', 5)    # sp for target med param

# Define zero Boundary conditions:
def u0_boundary(x, on_boundary):
    return on_boundary
u0 = Constant("0.0")
bc = DirichletBC(V, u0, u0_boundary)

# Define target medium and rhs:
mtrue_exp = Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \
' pow(x[1] - 0.5,2),0.5) > 0.2)')
#mtrue = interpolate(mtrue_exp, Vme)
mtrue = interpolate(mtrue_exp, Vm)
f = Expression("1.0")

# Assemble weak form
trial = TrialFunction(V)
test = TestFunction(V)
a_true = inner(mtrue*nabla_grad(trial), nabla_grad(test))*dx
A_true = assemble(a_true)
bc.apply(A_true)
solver = PETScKrylovSolver('cg')    # doesn't work with ilu preconditioner
Esempio n. 37
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop, degree=self.deg)
        wBottom = Expression(self.wBottom, degree=self.deg)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v))*wTop*dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue)*u*v*wTop*ds(bc.value+shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(bc.parValue)*u*v*wBottom*ds(bc.value+shift)
        else:
            m = u*v*wBottom*dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
            # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift+1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift+1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf