Пример #1
0
def get_bc_parts(mesh, lst):
    """
    Build a size_t function with boundary condition parts.

    Returns all Robin and Steklov conditions that need to be applied,
    the shift needed to get a nonnegative function,
    and the function itself.
    """
    if len(lst) > 0:
        shift = max(0, -min(e.value for e in lst))
    else:
        return [], [], 0, FacetFunction("size_t", mesh, 0)
    # values must be shifted by smallest Steklov value since size_t is unsigned
    fun = FacetFunction("size_t", mesh, shift)
    for bc in lst:
        sub = OnBoundary()
        # overwrite inside function with the one from bc
        sub.inside = bc.getTest()
        sub.mark(fun, bc.value + shift)
    # some conditions may cancel eachother
    exist = set(np.unique(fun.array()))
    lst = [e for e in lst if e.value + shift in exist]
    # separate Robin and Steklov, Dirichlet and Neumann are irrelevant
    Robin = [e for e in lst if e.value > 1 and e.parValue != 0]
    Steklov = [e for e in lst if e.value < 0 and e.parValue != 0]
    return Robin, Steklov, shift, fun
Пример #2
0
def mark_conditions(mesh, lst):
    """ Mark all boundary conditions from the list. """
    fun = FacetFunction("int", mesh, 0)
    for bc in lst:
        sub = OnBoundary()
        # overwrite inside function with the one from bc
        sub.inside = bc.getTest()
        sub.mark(fun, bc.value)
    return fun.array()
Пример #3
0
def test_store_mesh(casedir):
    pp = PostProcessor(dict(casedir=casedir))

    from dolfin import (UnitSquareMesh, CellFunction, FacetFunction,
                        AutoSubDomain, Mesh, HDF5File, assemble, Expression,
                        ds, dx)

    # Store mesh
    mesh = UnitSquareMesh(6, 6)
    celldomains = CellFunction("size_t", mesh)
    celldomains.set_all(0)
    AutoSubDomain(lambda x: x[0] < 0.5).mark(celldomains, 1)

    facetdomains = FacetFunction("size_t", mesh)
    AutoSubDomain(lambda x, on_boundary: x[0] < 0.5 and on_boundary).mark(
        facetdomains, 1)

    pp.store_mesh(mesh, celldomains, facetdomains)

    # Read mesh back
    mesh2 = Mesh()
    f = HDF5File(mpi_comm_world(), os.path.join(pp.get_casedir(), "mesh.hdf5"),
                 'r')
    f.read(mesh2, "Mesh", False)

    celldomains2 = CellFunction("size_t", mesh2)
    f.read(celldomains2, "CellDomains")
    facetdomains2 = FacetFunction("size_t", mesh2)
    f.read(facetdomains2, "FacetDomains")

    e = Expression("1+x[1]", degree=1)

    dx1 = dx(1, domain=mesh, subdomain_data=celldomains)
    dx2 = dx(1, domain=mesh2, subdomain_data=celldomains2)
    C1 = assemble(e * dx1)
    C2 = assemble(e * dx2)
    assert abs(C1 - C2) < 1e-10

    ds1 = ds(1, domain=mesh, subdomain_data=facetdomains)
    ds2 = ds(1, domain=mesh2, subdomain_data=facetdomains2)
    F1 = assemble(e * ds1)
    F2 = assemble(e * ds2)
    assert abs(F1 - F2) < 1e-10
Пример #4
0
def as_pvd(h5_file):
    '''Store facet and cell function for pvd'''
    root, ext = os.path.splitext(h5_file)

    mesh = Mesh()
    hdf = HDF5File(mesh.mpi_comm(), h5_file, 'r')
    hdf.read(mesh, '/mesh', False)

    facet_markers = FacetFunction('size_t', mesh)
    hdf.read(facet_markers, '/facet_markers')

    cell_markers = CellFunction('size_t', mesh)
    hdf.read(cell_markers, '/cell_markers')

    File(root + 'facets' + '.pvd') << facet_markers
    File(root + 'volumes' + '.pvd') << cell_markers

    return True
Пример #5
0
def derived_bcs(V, original_bcs, u_):

    new_bcs = []

    # Check first if user has declared subdomains
    subdomain = original_bcs[0].user_sub_domain()
    if subdomain is None:
        mesh = V.mesh()
        ff = FacetFunction("size_t", mesh, 0)
        for i, bc in enumerate(original_bcs):
            bc.apply(u_[0].vector())  # Need to initialize bc
            m = bc.markers()  # Get facet indices of boundary
            ff.array()[m] = i + 1
            new_bcs.append(DirichletBC(V, Constant(0), ff, i + 1))

    else:
        for i, bc in enumerate(original_bcs):
            subdomain = bc.user_sub_domain()
            new_bcs.append(DirichletBC(V, Constant(0), subdomain))

    return new_bcs
Пример #6
0
def les_setup(u_, mesh, Wale, bcs, CG1Function, nut_krylov_solver, **NS_namespace):
    """Set up for solving Wale LES model
    """
    DG = FunctionSpace(mesh, "DG", 0)
    CG1 = FunctionSpace(mesh, "CG", 1)
    
    # Compute cell size and put in delta
    delta = Function(DG)
    delta.vector().zero()
    delta.vector().axpy(1.0, assemble(TestFunction(DG)*dx))
    
    # Set up Wale form
    Gij = grad(u_)
    Sij = sym(Gij)
    Skk = tr(Sij)
    dim = mesh.geometry().dim()
    Sd = sym(Gij*Gij) - 1./3.*Identity(mesh.geometry().dim())*Skk*Skk 
    nut_form = Wale['Cw']**2 * pow(delta, 2./dim) * pow(inner(Sd, Sd), 1.5) / (Max(pow(inner(Sij, Sij), 2.5) + pow(inner(Sd, Sd), 1.25), 1e-6))
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = derived_bcs(CG1, bcs['u0'], u_)
    nut_ = CG1Function(nut_form, mesh, method=nut_krylov_solver, bcs=bcs_nut, name='nut', bounded=True)
    return dict(Sij=Sij, Sd=Sd, Skk=Skk, nut_=nut_, delta=delta, bcs_nut=bcs_nut)
Пример #7
0
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs,
              **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij,
                nut_form=nut_form,
                nut_=nut_,
                delta=delta,
                bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq,
                CG1=CG1,
                Cs=Cs,
                u_CG1=u_CG1,
                u_filtered=u_filtered,
                ll=ll,
                Lij=Lij,
                Mij=Mij,
                Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps,
                Sijmats=Sijmats,
                JLM=JLM,
                JMM=JMM,
                dim=dim,
                tensdim=tensdim,
                G_matr=G_matr,
                G_under=G_under,
                dummy=dummy,
                uiuj_pairs=uiuj_pairs)
Пример #8
0
def marked_boundary(mesh):
    """ Return array of vertex values with 1 on boundary, 0 otherwise. """
    fun = FacetFunction("int", mesh, 0)
    on = OnBoundary()
    on.mark(fun, 1)
    return fun.array()
Пример #9
0
    if mpirank == 0: print 'Start assembling KV'
    MPI.barrier(mpicomm)
    t0 = time()
    KV = assemble(weak_V)
    MPI.barrier(mpicomm)
    t1 = time()
    if mpirank == 0: print 'Time to assemble KV = {}'.format(t1 - t0)
elif myrun == 2:

    class LeftRight(SubDomain):
        def inside(self, x, on_boundary):
            return (x[0] < 1e-16 or x[0] > 1.0 - 1e-16) \
            and on_boundary

    class_bc_abc = LeftRight()
    abc_boundaryparts = FacetFunction("size_t", mesh)
    class_bc_abc.mark(abc_boundaryparts, 1)
    ds = Measure("ds")[abc_boundaryparts]
    weak_1 = inner(sqrt(lam1 * rho1) * nabla_grad(trial),
                   nabla_grad(test)) * ds(1)
    weak_2 = inner(sqrt(lam2 * rho2) * nabla_grad(trial),
                   nabla_grad(test)) * ds(1)

    lam1.vector()[:] = 1.0
    rho1.vector()[:] = 1.0
    print 'Start assembling K2'
    t0 = time()
    K2 = assemble(weak_2)
    t1 = time()
    print 'Time to assemble K2 = {}'.format(t1 - t0)
Пример #10
0
def construct_sleeve_geometry(
    t_wall=None,
    t_gap=None,
    t_sleeve=None,
    L_wall=None,
    L_sleeve=None,
    refinement_parameter=16,
):
    #
    # Define the domain as a polygon
    mesh = Mesh()
    domain = Polygon([
        dolfin.Point(0.0, 0.0),
        dolfin.Point(L_wall, 0.0),
        dolfin.Point(L_wall, t_wall),
        dolfin.Point((L_wall - L_sleeve), t_wall),
        dolfin.Point((L_wall - L_sleeve), (t_wall + t_gap)),
        dolfin.Point(L_wall, (t_wall + t_gap)),
        dolfin.Point(L_wall, (t_sleeve + t_wall + t_gap)),
        dolfin.Point((L_wall - L_sleeve), (t_sleeve + t_wall + t_gap)),
        dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall),
        dolfin.Point(0.0, t_wall),
    ], )
    #
    # Define weld region
    weld_subdomain = Polygon([
        dolfin.Point((L_wall - L_sleeve - t_sleeve - t_gap), t_wall),
        dolfin.Point((L_wall - L_sleeve), t_wall),
        dolfin.Point((L_wall - L_sleeve), (t_wall + t_sleeve + t_gap)),
    ])
    domain.set_subdomain(1, weld_subdomain)
    #
    # Mesh
    mesh = generate_mesh(domain, refinement_parameter)
    #
    # Refine in the weld
    cell_markers = CellFunction("bool", mesh)
    cell_markers.set_all(False)
    c = is_in_weld_region(
        t_wall=t_wall,
        t_gap=t_gap,
        t_sleeve=t_sleeve,
        L_wall=L_wall,
        L_sleeve=L_sleeve,
    )

    class MyDomain(SubDomain):
        def inside(self, x, on_boundary):
            return c(x)

    my_domain = MyDomain()
    my_domain.mark(cell_markers, True)
    mesh = refine(mesh, cell_markers)

    #
    # Define the upper and lower boundaries
    class Upper(SubDomain):
        def inside(self, x, on_boundary):
            #
            # Define relevant points
            xb1 = (L_wall - L_sleeve - t_sleeve - t_gap)
            xb2 = (L_wall - L_sleeve)
            yb1 = t_wall
            yb2 = (t_wall + t_sleeve + t_gap)
            #
            # Define params for assessing if on a line between points
            dx_line = xb2 - xb1
            dy_line = yb2 - yb1
            dx = x[0] - xb1
            dy = x[1] - yb1
            zero = dx * dy_line - dx_line * dy
            #
            is_upper_region_one = x[0] <= xb1 and near(x[1], yb1)
            is_upper_region_two = x[0] >= xb1 and x[0] <= xb2 and near(zero, 0)
            is_upper_region_three = x[0] >= xb2 and near(x[1], yb2)
            #
            return is_upper_region_one or is_upper_region_two or is_upper_region_three

    class Lower(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[1], 0)

    #
    # Set boundaries
    upper = Upper()
    lower = Lower()
    boundaries = FacetFunction("size_t", mesh)
    boundaries.set_all(0)
    upper.mark(boundaries, 1)
    lower.mark(boundaries, 2)
    #
    return (mesh, boundaries)
Пример #11
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)
        wBottom = Expression(self.wBottom)

        #
        # 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
Пример #12
0
class InflowBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary and near(x[0], x_min)


class NoslipBoundary(SubDomain):
    def inside(self, x, on_boundary):
        dx = x[0] - c_x
        dy = x[1] - c_y
        dr = sqrt(dx**2 + dy**2)
        return on_boundary and (near(x[1] *
                                     (y_max - x[1]), 0) or dr < r + 1E-3)


f_f = FacetFunction('size_t', mesh, 0)
InflowBoundary().mark(f_f, 13)
NoslipBoundary().mark(f_f, 12)


# Width of the L domain
def compute_width_L_cylinder(unit):
    return 4 * unit + 4 * unit * cos(pi / 4)


# Width of the O domain
def compute_width_O_cylinder(unit):
    return 4 * unit


class InflowProfileConstant(Expression):