Example #1
0
def setup_mms():
    '''Simple MMS problem for UnitSquareMesh'''
    mesh = UnitSquareMesh(2, 2)
    # The following labeling of edges will be enforced
    #   4
    # 1   2
    #   3
    subdomains = {1: CompiledSubDomain('near(x[0], 0)'),
                  2: CompiledSubDomain('near(x[0], 1)'),
                  3: CompiledSubDomain('near(x[1], 0)'),
                  4: CompiledSubDomain('near(x[1], 1)')}
    
    x, y  = SpatialCoordinate(mesh)
    u = as_vector((sin(pi*(x+y)),
                   cos(pi*(x-y))))
    
    # LM is defined as -div(u), in addition when specifying bcs Hdiv uses
    # sigma, so no need for normal
    p = -div(u)

    f = -grad(div(u)) + u
    g_u = [u]*4  

    to_expr = lambda f: ulfy.Expression(f, degree=4)
    
    w = tuple(to_expr(x) for x in (u, p))

    return {'solution': w,
            'force': to_expr(f),
            'u': dict(enumerate(map(to_expr, g_u), 1)),
            'subdomains': subdomains}
Example #2
0
def mms_solid(parameters):
    '''Method of manufactured solutions on [0, 1]^2'''
    mesh = UnitSquareMesh(MPI.comm_self, 2, 2)  
    V = VectorFunctionSpace(mesh, 'CG', 2)  # Displacement, Flux
    Q = FunctionSpace(mesh, 'CG', 2)  # Pressure
    # Coefficient space
    S = FunctionSpace(mesh, 'DG', 0)

    kappa, mu, lmbda, alpha, s0 = [Function(S) for _ in range(5)]

    eta = Function(V)  # Displacement
    p = Function(Q)  # Pressure
    u = -kappa*grad(p)  # Define flux

    pT = -lmbda*div(eta) + alpha*p  # Total pressure

    sigma_p = lambda eta, p: 2*mu*sym(grad(eta)) + lmbda*div(eta)*Identity(len(eta)) - alpha*p*Identity(len(eta))
    
    f1 = -div(sigma_p(eta, p))
    
    # NOTE: we do not have temporal derivative but if we assume eta and p
    # have foo(x, y)*bar(t) then in mass conservation we will have
    # [s0*p + alpha*div(eta)]*dbar(t)
    
    # What we want to substitute
    x, y, kappa_, mu_, lmbda_, alpha_, s0_ = sp.symbols('x y kappa mu lmbda alpha s0')
    time_ = sp.Symbol('time')
    # Expressions
    eta_ = sp.Matrix([sp.sin(pi*(x + y)),
                      sp.cos(pi*(x + y))])*sp.exp(1-time_)

    p_ = sp.cos(pi*(x-y))*sp.exp(1-time_)
    # - here is dbar(t)
    f2 = -(s0*p + alpha*div(eta)) + div(u)

    subs = {eta: eta_, p: p_,
            kappa: kappa_, mu: mu_, lmbda: lmbda_, alpha: alpha_, s0: s0_}

    as_expr = lambda t: ulfy.Expression(t, subs=subs, degree=4,
                                        kappa=parameters['kappa'],
                                        mu=parameters['mu'],
                                        lmbda=parameters['lmbda'],
                                        alpha=parameters['alpha'],
                                        s0=parameters['s0'],
                                        time=0.0)
    
    # Solution
    eta_exact, u_exact, p_exact, pT_exact = map(as_expr, (eta, u, p, pT))
    # Forcing
    f1, f2 = as_expr(f1), as_expr(f2)
    #  4
    # 1 2
    #  3 so that
    normals = [Constant((-1, 0)), Constant((1, 0)), Constant((0, -1)), Constant((0, 1))]
    tractions = [as_expr(dot(sigma_p(eta, p), n)) for n in normals]

    return {'solution': (eta_exact, u_exact, p_exact, pT_exact),
            'force': (f1, f2),
            'tractions': tractions}
Example #3
0
def setup_mms(parameter_values):
    '''Manufacture solution for the immersed test case'''
    mesh = UnitSquareMesh(2, 2, 'crossed')

    x, y = SpatialCoordinate(mesh)
    kappa0, kappa1 = Constant(1), Constant(1)

    u0 = sin(pi*(x-2*y))
    u1 = cos(2*pi*(3*x-y))

    sigma0 = kappa0*grad(u0)
    sigma1 = kappa1*grad(u1)

    f0 = -div(sigma0)
    f1 = -div(sigma1)
    
    # Interface is oriented based on outer
    normalsI = tuple(map(Constant, ((1, 0), (-1, 0), (0, 1), (0, -1))))    
    # Neumann and Robin interface data
    g_n = tuple(dot(sigma0, n) - dot(sigma1, n) for n in normalsI)
    g_r = tuple(u0 - u1 + dot(sigma0, n) for n in normalsI)
    # True multiplier value
    lms = [-dot(sigma0, n) for n in normalsI]

    # Don't want to trigger compiler on parameter change
    kappa0_, kappa1_ = sp.symbols('kappa0 kappa1')
    subs = {kappa0: kappa0_, kappa1: kappa1_}

    # Check coefs
    assert parameter_values['kappa0'] > 0 and parameter_values['kappa1'] > 0

    to_expr = lambda f: ulfy.Expression(f, degree=4, subs=subs,
                                        kappa0=parameter_values['kappa0'],
                                        kappa1=parameter_values['kappa1'])

    # As tagged in utils.immersed_geometry
    lm_subdomains = {
        1: CompiledSubDomain('near(x[0], 0.25) && ((0.25-DOLFIN_EPS < x[1]) && (x[1] < 0.75+DOLFIN_EPS))'),
        2: CompiledSubDomain('near(x[0], 0.75) && ((0.25-DOLFIN_EPS < x[1]) && (x[1] < 0.75+DOLFIN_EPS))'),
        3: CompiledSubDomain('near(x[1], 0.25) && ((0.25-DOLFIN_EPS < x[0]) && (x[0] < 0.75+DOLFIN_EPS))'),
        4: CompiledSubDomain('near(x[1], 0.75) && ((0.25-DOLFIN_EPS < x[0]) && (x[0] < 0.75+DOLFIN_EPS))')
    }
    
    return {
        'solution': {'u0': to_expr(u0), 'u1': to_expr(u1),
                     'lm': PiecewiseExpression(lm_subdomains, dict(enumerate(map(to_expr, lms), 1)))},
        'f0': to_expr(f0),
        'f1': to_expr(f1),
        # Standard boundary data
        'dirichlet_0': dict(enumerate(map(to_expr, [u0]*8), 1)),
        # Interface boundary conditions
        'g_n': dict(enumerate(map(to_expr, g_n), 1)),
        'g_r': dict(enumerate(map(to_expr, g_r), 1)),
        # Geometry setup
        'get_geometry': immersed_geometry
    }
Example #4
0
def setup_mms(Bop):
    '''Simple MMS problem for UnitSquareMesh'''
    mesh = UnitSquareMesh(2, 2)
    # The following labeling of edges will be enforced
    #   4
    # 1   2
    #   3
    subdomains = {
        1: CompiledSubDomain('near(x[0], 0)'),
        2: CompiledSubDomain('near(x[0], 1)'),
        3: CompiledSubDomain('near(x[1], 0)'),
        4: CompiledSubDomain('near(x[1], 1)')
    }

    x, y = SpatialCoordinate(mesh)
    u = as_vector((sin(pi * (x - 2 * y)), cos(2 * pi * (x + y))))

    sigma = sym(grad(u))
    f = -div(sigma) + u

    # For LM We have -sigma.n as LM  when Bu = u
    #                -sigma.n.n      when Bu = u.n
    #                -sigma.n.t      when Bu = u.t
    normals = (Constant((-1, 0)), Constant((1, 0)), Constant(
        (0, -1)), Constant((0, 1)))
    R = Constant(((0, 1), (-1, 0)))

    lm = [-dot(sigma, n) for n in normals]
    lm_n = [dot(l, n) for l, n in zip(lm, normals)]
    lm_t = [dot(l, dot(R, n)) for l, n in zip(lm, normals)]

    to_expr = lambda f: ulfy.Expression(f, degree=4)

    # Multiplier is traction
    if Bop == 'full':
        lm_ = dict(enumerate(map(to_expr, lm), 1))
    # LM is traction components
    elif Bop == 'normal':
        lm_ = dict(enumerate(map(to_expr, lm_n), 1))
    else:
        assert Bop == 'tangent'
        lm_ = dict(enumerate(map(to_expr, lm_t), 1))

    up = (to_expr(u), PiecewiseExpression(subdomains, lm_))

    return {
        'solution': up,
        'f': to_expr(f),
        'dirichlet': dict(enumerate(map(to_expr, [u] * 4), 1)),
        # Will select proper component from traction
        'neumann':
        {tag: to_expr(dot(sigma, n))
         for tag, n in enumerate(normals, 1)},
        'subdomains': subdomains
    }
def setup_mms(eps=None):
    '''Simple MMS problem for UnitSquareMesh'''
    import sympy as sp
    import ulfy

    mesh = UnitSquareMesh(2, 2)

    V = VectorFunctionSpace(mesh, 'CG', 1)
    u = Function(V)

    # Define as function to allow ufly substition
    S = FunctionSpace(mesh, 'DG', 0)
    mu = Function(S)
    lmbda = Function(S)

    sigma = lambda u: 2 * mu * sym(grad(u)) + lmbda * div(u) * Identity(2)

    # The form
    f = -div(sigma(u))
    p = lmbda * div(u)  # Solid pressure

    # What we want to substitute
    x, y, mu_, lambda_ = sp.symbols('x y mu lmbda')
    # I chose u purposely such that sigma(u).n is zero on the boundary
    u_ = sp.Matrix([
        0.01 * sp.cos(sp.pi * x * (1 - x) * y * (1 - y)),
        -0.01 * sp.cos(2 * sp.pi * x * (1 - x) * y * (1 - y))
    ])
    x_ = sp.Matrix([0, 0])

    subs = {u: u_, mu: mu_, lmbda: lambda_}  # Function are replaced by symbols
    # As expressions
    up = (ulfy.Expression(u_, degree=5),
          ulfy.Expression(p, subs=subs, degree=4, mu=eps[0],
                          lmbda=eps[1]), ulfy.Expression(x_, degree=1))
    # Note lmbda_ being a constant is compiled into constant so errornorm
    # will complaing about the Expressions's degree being too low
    fg = (ulfy.Expression(f, subs=subs, degree=4, mu=eps[0], lmbda=eps[1]),
          ulfy.Expression(u_, degree=4, mu=eps[0],
                          lmbda=eps[1]))  # mu, lmbda are are given value

    return up, fg
Example #6
0
def mms_ad(kappa_value):
    '''Method of manufactured solutions on [0, 1]^2'''
    mesh = UnitSquareMesh(2, 2)  # Dummy
    V = FunctionSpace(mesh, 'CG', 2)
    # Coefficient space
    S = FunctionSpace(mesh, 'DG', 0)
    kappa, alpha = Function(S), Function(S)
    # Velocity
    W = VectorFunctionSpace(mesh, 'CG', 1)
    velocity = Function(W)

    c = Function(V)
    # foo*exp(1-alpha*time) so that d / dt gives us -alpha*foo
    f = -alpha * c + dot(velocity, grad(c)) - kappa * div(grad(c))

    flux = lambda c, n, kappa=kappa: dot(kappa * grad(c), n)

    # What we want to substitute
    x, y, kappa_ = sp.symbols('x y kappa')
    time_, alpha_ = sp.symbols('time alpha')
    velocity_ = sp.Matrix([-(y - 0.5), (x - 0.5)])

    # Expressions
    c_ = sp.sin(pi * (x + y)) * sp.exp(1 - alpha_ * time_)

    subs = {c: c_, kappa: kappa_, alpha: alpha_, velocity: velocity_}
    as_expr = lambda t: ulfy.Expression(
        t, subs=subs, degree=4, kappa=kappa_value, alpha=2, time=0.)

    # Solution
    c_exact, velocity = map(as_expr, (c, velocity))
    # Forcing
    f = as_expr(f)

    normals = [
        Constant((-1, 0)),
        Constant((1, 0)),
        Constant((0, -1)),
        Constant((0, 1))
    ]
    fluxes = [as_expr(flux(c, n)) for n in normals]

    return {
        'solution': c_exact,
        'forcing': f,
        'fluxes': fluxes,
        'velocity': velocity
    }
Example #7
0
def setup_mms():
    '''Simple MMS problem for UnitSquareMesh'''
    mesh = UnitSquareMesh(2, 2)
    
    x, y  = SpatialCoordinate(mesh)
    u = cos(pi*x*(1-x)*y*(1-y))
    p = Constant(0)

    f = -div(grad(u)) + u
    g = u

    to_expr = lambda f: ulfy.Expression(f, degree=4)
    
    up = tuple(to_expr(x) for x in (u, p))
    fg = tuple(to_expr(x) for x in (f, g))

    return {'solution': up, 'data': fg}
Example #8
0
def setup_mms():
    '''Simple MMS problem for UnitSquareMesh'''
    mesh = UnitSquareMesh(2, 2)
    
    x, y  = SpatialCoordinate(mesh)
    
    phi = sin(pi*(x+y))
    u = as_vector((phi.dx(1), -phi.dx(0)))

    p = cos(pi*x)*cos(pi*y)
    sigma = 2*sym(grad(u)) - p*Identity(2)

    f = -div(sigma)
    g_u = u
    
    to_expr = lambda f: ulfy.Expression(f, degree=4)
    
    w = tuple(to_expr(x) for x in (u, p))

    return {'solution': w,
            'force': to_expr(f),
            'velocity': to_expr(g_u)}
Example #9
0
File: ale.py Project: MiroK/sleep
def mms_ale(kappa_value):
    '''Method of manufactured solutions on [0, 1]^2'''
    mesh = UnitSquareMesh(2, 2)  # Dummy
    V = VectorFunctionSpace(mesh, 'CG', 2)
    # Coefficient space
    S = FunctionSpace(mesh, 'DG', 0)
    kappa = Function(S)

    u = Function(V)
    f = -div(kappa * grad(u))
    flux = lambda u, n, kappa=kappa: dot(kappa * grad(u), n)

    # What we want to substitute
    x, y, kappa_ = sp.symbols('x y kappa')
    # Expressions
    u_ = sp.Matrix([sp.sin(pi * (x + y)), sp.cos(pi * (x + y))])

    subs = {u: u_, kappa: kappa_}  # Function are replaced by symbols

    as_expr = lambda t: ulfy.Expression(
        t, subs=subs, degree=4, kappa=kappa_value)

    # Solution
    u_exact = as_expr(u)
    # Forcing
    f = as_expr(f)
    #  4
    # 1 2
    #  3 so that
    normals = [
        Constant((-1, 0)),
        Constant((1, 0)),
        Constant((0, -1)),
        Constant((0, 1))
    ]
    fluxes = [as_expr(flux(u, n)) for n in normals]

    return {'solution': u_exact, 'force': f, 'fluxes': fluxes}
Example #10
0
    from dolfin import *
    import numpy as np
    import sympy as sp
    import ulfy

    n = 64

    mesh = UnitSquareMesh(n, n)
    V = VectorFunctionSpace(mesh, 'CG', 2)

    x, y = sp.symbols('x y')
    u = Function(V)
    n = Constant((1, 0))

    subs = {u: sp.Matrix([sp.sin(x**2 + y**2), sp.cos(x**2 - 3 * y**2)])}
    displacement = ulfy.Expression(u, subs=subs, degree=2)
    stress = ulfy.Expression(sym(grad(u)), subs=subs, degree=2)
    traction = ulfy.Expression(dot(n, sym(grad(u))), subs=subs, degree=2)
    traction_n = ulfy.Expression(dot(n, dot(n, sym(grad(u)))),
                                 subs=subs,
                                 degree=2)
    displacement_n = ulfy.Expression(dot(u, n) * n, subs=subs, degree=2)

    cell_f = MeshFunction('size_t', mesh, 2, 2)
    CompiledSubDomain('x[0] < 0.5+DOLFIN_EPS').mark(cell_f, 1)

    left = EmbeddedMesh(cell_f, 1)
    left_bdries = MeshFunction('size_t', left, 1, 0)
    CompiledSubDomain('near(x[0], 0.5)').mark(left_bdries, 1)

    right = EmbeddedMesh(cell_f, 2)
Example #11
0
def setup_mms(params):
    '''
    Simple MMS problem for UnitSquareMesh. Return MMSData.
    '''
    mesh = UnitSquareMesh(mpi_comm_self(), 2, 2)  # Dummy

    V = FunctionSpace(mesh, 'CG', 2)
    S = FunctionSpace(mesh, 'DG', 0)
    # Define as function to allow ufly substition
    kappa, kappa1, eps = Function(S), Function(S), Function(S)

    u = Function(V)
    sigma = kappa * grad(u)
    # Outer normals of inner
    normals = map(Constant, [(-1, 0), (1, 0), (0, -1), (0, 1)])

    # Forcing for first
    f = -div(sigma)

    # Second and its forcing
    u1 = Function(V)
    sigma1 = kappa1 * grad(u1)
    f1 = -div(sigma1)

    # On interface we have difference in us (restricted)
    gGamma_i = lambda n: u1 - u - eps * dot(sigma, n)
    hGamma_i = lambda n: -dot(sigma1, n) + dot(sigma, n)

    # Multiplier is u1| restricted!

    # What we want to substitute
    x, y, kappa1_, kappa_, eps_ = sp.symbols('x y kappa1 kappa eps')

    u_ = sp.sin(pi * (x + y))
    #u1_ = u_/kappa1_ + (x-0.25)**2*(x-0.75)**2*(y-0.25)**2*(y-0.75)**2  # u1 - u1 = 0 so simple!
    u1_ = u_ / kappa1_ + sp.cos(pi * (x - 0.25) *
                                (x - 0.75)) * sp.cos(pi * (y - 0.25) *
                                                     (y - 0.75))

    subs = {u: u_, u1: u1_, kappa: kappa_, kappa1: kappa1_, eps: eps_}

    as_expression = lambda f: ulfy.Expression(
        f, subs=subs, degree=4, kappa=1, kappa1=params.kappa, eps=params.eps)

    # Solutions
    u_exact = as_expression(u)
    sigma_exact = as_expression(sigma)

    u1_exact = as_expression(u1)
    sigma1_exact = as_expression(sigma1)

    # Mulltiplier is du on the boundary
    p_exact = as_expression(u1 - u)
    I_exact = [as_expression(dot(sigma, n)) for n in normals]  # current

    # Data
    f = as_expression(f)
    f1 = as_expression(f1)
    # Dirichle data for outer boundary (piecewise)
    gBdry = [u1_exact] * 4
    # Temperature jump (piecewise)
    gGamma = [as_expression(gGamma_i(n)) for n in normals]
    # Flux jump
    hGamma = [as_expression(hGamma_i(n)) for n in normals]

    rhs = (f1, f, gBdry, gGamma, hGamma)
    # Subdomains for the outerboundary then interfaces then extra/intracelluler
    inside = [
        '(0.25-tol<x[0])', '(x[0] < 0.75+tol)', '(0.25-tol<x[1])',
        '(x[1] < 0.75+tol)'
    ]
    inside = ' && '.join(inside)

    outside = '!(%s)' % inside

    subdomains = [('near(x[0], 0.0)', 'near(x[0], 1.0)', 'near(x[1], 0.0)',
                   'near(x[1], 1.0)'),
                  ('near(x[0], 0.25)', 'near(x[0], 0.75)', 'near(x[1], 0.25)',
                   'near(x[1], 0.75)'), (outside, inside)]
    # Solutions for inside and outside
    return MMSData(solution=[[sigma1_exact, sigma_exact], [u1_exact, u_exact],
                             p_exact, I_exact],
                   rhs=rhs,
                   subdomains=subdomains,
                   normals=[normals, normals])
Example #12
0
def foo(n):
    mesh = UnitSquareMesh(n, n)
    V = VectorFunctionSpace(mesh, 'CG', 2)

    x, y = sp.symbols('x y')
    u = Function(V)
    n = Constant((1, 0))

    subs = {u: sp.Matrix([sp.sin(x**2 + y**2), sp.cos(x**2 - 3 * y**2)])}
    displacement = ulfy.Expression(u, subs=subs, degree=2)
    stress = ulfy.Expression(sym(grad(u)), subs=subs, degree=2)
    traction = ulfy.Expression(dot(n, sym(grad(u))), subs=subs, degree=2)

    cell_f = MeshFunction('size_t', mesh, 2, 2)
    CompiledSubDomain('x[0] < 0.5+DOLFIN_EPS').mark(cell_f, 1)

    left = EmbeddedMesh(cell_f, 1)
    left_bdries = MeshFunction('size_t', left, 1, 0)
    CompiledSubDomain('near(x[0], 0.5)').mark(left_bdries, 1)

    interface = EmbeddedMesh(left_bdries, 1)

    right = EmbeddedMesh(cell_f, 2)
    right_bdries = MeshFunction('size_t', right, 1, 0)
    CompiledSubDomain('near(x[0], 0.5)').mark(right_bdries, 2)
    # Don't redefine!
    interface.compute_embedding(right_bdries, 2)

    # Okay so let's be on left with displacement
    V = VectorFunctionSpace(left, 'CG', 2)
    u = interpolate(displacement, V)
    # Is this a way to compute the stress?
    Q = VectorFunctionSpace(left, 'DG', 1)
    q = TestFunction(Q)  # Use DG1?
    n = FacetNormal(left)

    expr = dot(sym(grad(u)), n)
    ds_ = Measure('ds', domain=left, subdomain_data=left_bdries)
    b = assemble(inner(expr, q) * ds_(1))

    # This
    B = VectorFunctionSpace(interface, 'DG',
                            1)  # Match the test function of form
    MTb = Function(B)
    trace_matrix(Q, B, interface).mult(b, MTb.vector())
    # Now y is in the dual. we need it back
    x = Function(B)
    M = assemble(inner(TrialFunction(B), TestFunction(B)) * dx)
    solve(M, x.vector(), MTb.vector())
    # x is now expr|_interface

    print assemble(inner(x - traction, x - traction) * dx)

    # What I want to do next is to extend it to right domain so that
    # if I there perform surface integral over the interface I get close
    # to what the left boundary said

    R = VectorFunctionSpace(right, 'DG', 1)
    extend = Function(R)
    trace_matrix(R, B, interface).transpmult(x.vector(), extend.vector())

    import matplotlib.pyplot as plt

    xx = np.sort([cell.midpoint().array()[1] for cell in cells(interface)])

    yy = np.array([x(0.5, xxi)[0] for xxi in xx])
    zz = np.array([traction(0.5, xxi)[0] for xxi in xx])
    rr = np.array([extend(0.5, xxi)[0] for xxi in xx])

    plt.figure()
    plt.plot(xx, yy, label='num')
    plt.plot(xx, zz, label='true')
    plt.plot(xx, rr, label='rec')
    plt.legend()
    plt.show()
Example #13
0
def mms_stokes(mu_value, rho_value):
    '''Method of manufactured solutions on [0, 1]^2'''
    mesh = UnitSquareMesh(2, 2)  # Dummy
    V = FunctionSpace(mesh, 'CG', 2)
    # Coefficient space
    S = FunctionSpace(mesh, 'DG', 0)
    mu, rho, alpha, time = Function(S), Function(S), Function(S), Function(S)

    # Auxiliry function for defining Stokes velocity (to make it div-free)
    phi = Function(V)

    u = as_vector((phi.dx(1), -phi.dx(0))) * exp(1 - alpha**2 * time)
    p = Function(V)  # Pressure

    stress = lambda u, p, mu=mu: mu * grad(u) - p * Identity(len(u))

    # Forcing for Stokes
    f = -div(stress(u, p)) / rho + u * (-alpha**2)
    # We will also need traction on boundaries with normal n
    traction = lambda u, p, n: dot(stress(u, p), n)

    # What we want to substitute
    x, y, mu_, rho_, alpha_, time_ = sp.symbols('x y mu rho alpha time')
    # Expressions
    phi_ = sp.sin(pi * (x + y))
    p_ = sp.sin(2 * pi * x) * sp.sin(4 * pi * y)

    subs = {
        phi: phi_,
        p: p_,
        mu: mu_,
        rho: rho_,
        alpha: alpha_,
        time: time_
    }  # Function are replaced by symbols

    as_expr = lambda t: ulfy.Expression(
        t, subs=subs, degree=4, mu=mu_value, rho=rho_value, alpha=0.2, time=0.)

    # Solution
    u_exact, p_exact = map(as_expr, (u, p))
    # Forcing
    f = as_expr(f)
    # With u, p we have things for Dirichlet and pressure boudaries. For
    # traction assume boundaries labeled in order
    #  4
    # 1 2
    #  3 so that
    normals = [
        Constant((-1, 0)),
        Constant((1, 0)),
        Constant((0, -1)),
        Constant((0, 1))
    ]
    tractions = [as_expr(traction(u, p, n)) for n in normals]
    # Finally tangential part
    R = Constant(((0, -1), (1, 0)))

    normal_comps = [as_expr(dot(n, traction(u, p, n))) for n in normals]
    tangent_comps = [
        as_expr(dot(dot(R, n), traction(u, p, n))) for n in normals
    ]
    stress_components = zip(normal_comps, tangent_comps)

    return {
        'solution': (u_exact, p_exact),
        'force': f,
        'tractions': tractions,
        'stress_components': stress_components
    }
Example #14
0
def setup_mms(flat_gamma):
    ''''''
    mesh = UnitSquareMesh(2, 2)
    # The following labeling of edges will be enforced
    #   4
    # 1   2
    #   3
    x, y = SpatialCoordinate(mesh)
    phi = sin(pi * (x - 2 * y))  # Auxiliary for div free velocity
    u = as_vector((phi.dx(1), -phi.dx(0)))
    p = cos(pi * (2 * x - 3 * y))

    sigma = 2 * sym(grad(u)) - p * Identity(2)
    f = -div(sigma)

    # Normal of gamma and how to construct the mesh then
    if flat_gamma:
        normals = (Constant((-1, 0)), )

        def get_geometry(i):
            n = 2 * 2**i
            mesh = UnitSquareMesh(n, n)

            facet_f = MeshFunction('size_t', mesh, 1, 0)
            CompiledSubDomain('near(x[0], 0)').mark(facet_f, 1)
            CompiledSubDomain('near(x[0], 1)').mark(facet_f, 2)
            CompiledSubDomain('near(x[1], 0)').mark(facet_f, 3)
            CompiledSubDomain('near(x[1], 1)').mark(facet_f, 4)

            return facet_f
    else:
        cx, cy, r = Constant(0), Constant(0.5), Constant(0.5)
        normals = (as_vector(((x - cx) / r, (y - cy) / r)), )

        try:
            import gmshnics, gmsh

            # We want to define
            #     /------|
            #    (       |
            #    (       |
            #     \------|

            def get_geometry(i):

                gmsh.initialize(['', '-clscale', str(1 / 2**i)])
                model = gmsh.model
                factory = model.occ

                ul = factory.addPoint(0, 1, 0)
                c = factory.addPoint(0, 0.5, 0)
                front = factory.addPoint(-0.5, 0.5, 0)
                ll = factory.addPoint(0, 0, 0)
                lr = factory.addPoint(1, 0, 0)
                ur = factory.addPoint(1, 1, 0)

                arc_top = factory.addCircleArc(ul, c, front)
                arc_bottom = factory.addCircleArc(front, c, ll)
                bottom = factory.addLine(ll, lr)
                right = factory.addLine(lr, ur)
                top = factory.addLine(ur, ul)

                loop = factory.addCurveLoop(
                    [arc_top, arc_bottom, bottom, right, top])
                domain = factory.addPlaneSurface([loop])

                factory.synchronize()

                model.addPhysicalGroup(2, [domain], 1)
                model.addPhysicalGroup(1, [arc_top, arc_bottom], 1)
                model.addPhysicalGroup(1, [right], 2)
                model.addPhysicalGroup(1, [bottom], 3)
                model.addPhysicalGroup(1, [top], 4)

                factory.synchronize()

                nodes, topologies = gmshnics.msh_gmsh_model(model, 2)
                mesh, entity_functions = gmshnics.mesh_from_gmsh(
                    nodes, topologies)

                gmsh.finalize()

                return entity_functions[1]

        except ImportError:
            print('Missing gmshnics module')
            get_geometry = lambda i: None

    # The remaining normals
    normals = normals + (Constant((1, 0)), Constant((0, -1)), Constant((0, 1)))

    R = Constant(((0, -1), (1, 0)))
    # In addition to u we will need data for Neumann boundaries and gamma
    g_dir = [u] * 4
    g_neu = [dot(sigma, n) for n in normals]
    # On LM boundary we have tangential data for velocity ...
    g_lm_t = [dot(u, dot(R, n)) for n in normals]
    # ... and also traction data in normal direction
    g_lm_n = [dot(dot(sigma, n), n) for n in normals]

    # For multiplier we have a setup in mind where it is defind only on
    # the left boundary
    lm, = (-dot(dot(R, n), dot(sigma, n)) for n in normals[:1])

    to_expr = lambda f: ulfy.Expression(f, degree=4)

    solution = tuple(map(to_expr, (u, p, lm)))

    return {
        'solution': solution,
        'f': to_expr(f),
        'dirichlet': dict(enumerate(map(to_expr, g_dir), 1)),
        'neumann': dict(enumerate(map(to_expr, g_neu), 1)),
        'lagrange_t': dict(enumerate(map(to_expr, g_lm_t), 1)),
        'lagrange_n': dict(enumerate(map(to_expr, g_lm_n), 1)),
        'get_geometry': get_geometry
    }
Example #15
0
def mms_solid(parameters):
    '''Method of manufactured solutions on [0, 1]^2'''
    mesh = UnitSquareMesh(2, 2)
    V = VectorFunctionSpace(mesh, 'CG', 2)  # Displacement, Flux
    Q = FunctionSpace(mesh, 'CG', 2)  # Pressure
    # Coefficient space
    S = FunctionSpace(mesh, 'DG', 0)

    kappa, mu, lmbda, alpha, s0 = [Function(S) for _ in range(5)]

    eta = Function(V)  # Displacement
    p = Function(Q)  # Pressure
    u = -kappa * grad(p)  # Define flux

    sigma_p = lambda eta, p: 2 * mu * sym(grad(eta)) + lmbda * div(
        eta) * Identity(len(eta)) - alpha * p * Identity(len(eta))

    f1 = -div(sigma_p(eta, p))

    # What we want to substitute
    x, y, kappa_, mu_, lmbda_, alpha_, s0_ = sp.symbols(
        'x y kappa mu lmbda alpha s0')

    # Expressions
    eta_ = sp.Matrix([sp.sin(pi * (x + y)), sp.cos(pi * (x + y))])

    p_ = sp.cos(pi * (x - y))

    f2 = (s0 * p + alpha * div(eta)) + div(u)  # Start with stationary first

    subs = {
        eta: eta_,
        p: p_,
        kappa: kappa_,
        mu: mu_,
        lmbda: lmbda_,
        alpha: alpha_,
        s0: s0_
    }

    as_expr = lambda t: ulfy.Expression(t,
                                        subs=subs,
                                        degree=4,
                                        kappa=parameters['kappa'],
                                        mu=parameters['mu'],
                                        lmbda=parameters['lmbda'],
                                        alpha=parameters['alpha'],
                                        s0=parameters['s0'])

    # Solution
    eta_exact, u_exact, p_exact = map(as_expr, (eta, u, p))
    # Forcing
    f1, f2 = as_expr(f1), as_expr(f2)
    #  4
    # 1 2
    #  3 so that
    normals = [
        Constant((-1, 0)),
        Constant((1, 0)),
        Constant((0, -1)),
        Constant((0, 1))
    ]
    tractions = [as_expr(dot(sigma_p(eta, p), n)) for n in normals]

    return {
        'solution': (eta_exact, u_exact, p_exact),
        'force': (f1, f2),
        'tractions': tractions
    }
Example #16
0
def setup_mms(parameter_values):
    '''Manufacture solution for the immersed test case'''
    # We take Stokes side as the master for normal orientation
    mesh = UnitSquareMesh(2, 2, 'crossed')

    x, y = SpatialCoordinate(mesh)
    mu, K, alpha = Constant(1), Constant(1), Constant(1)

    phi = sin(pi*(x-2*y))
    uS = as_vector((phi.dx(1), -phi.dx(0)))
    pS = cos(2*pi*(3*x-y))

    pD = sin(2*pi*(x+y))
    uD = -K*grad(pD)

    # Stokes ...
    sigma = 2*mu*sym(grad(uS)) - pS*Identity(2)
    fS = -div(sigma)
    # ... we need for standard boudaries velocity and traction.
    # NOTE: normals are assumed to be labeled as in immersed_geometry
    normalsS = tuple(map(Constant, ((1, 0), (-1, 0), (0, 1), (0, -1), (-1, 0), (1, 0), (0, -1), (0, 1))))
    traction = tuple(dot(sigma, n) for n in normalsS)
    
    # Darcy ...
    fD = div(uD)
    # ... we need pD and uD
    normalsD = tuple(map(Constant, ((-1, 0), (1, 0), (0, -1), (0, 1))))
    
    # Interface
    normalsI = tuple(map(Constant, ((1, 0), (-1, 0), (0, 1), (0, -1))))    

    g_u = tuple(dot(uS, n) - dot(uD, n) for n in normalsI)
    g_n = tuple(-dot(n, dot(sigma, n)) - pD for n in normalsI)
    g_t = tuple(-dot(rotate(n), dot(sigma, n)) - alpha*dot(rotate(n), uS) for n in normalsI)

    # Multiplier is -normal part of traction
    lms = [-dot(n, dot(sigma, n)) for n in normalsI]

    # Don't want to trigger compiler on parameter change
    mu_, alpha_, K_ = sp.symbols('mu, alpha, K')
    subs = {mu: mu_, alpha: alpha_, K: K_}

    # Check coefs
    assert parameter_values['mu'] > 0 and parameter_values['K'] > 0 and parameter_values['alpha'] >= 0

    to_expr = lambda f: ulfy.Expression(f, degree=4, subs=subs,
                                        mu=parameter_values['mu'],
                                        K=parameter_values['K'],
                                        alpha=parameter_values['alpha'])

    # As tagged in utils.immersed_geometry
    lm_subdomains = {
        1: CompiledSubDomain('near(x[0], 0.25) && ((0.25-DOLFIN_EPS < x[1]) && (x[1] < 0.75+DOLFIN_EPS))'),
        2: CompiledSubDomain('near(x[0], 0.75) && ((0.25-DOLFIN_EPS < x[1]) && (x[1] < 0.75+DOLFIN_EPS))'),
        3: CompiledSubDomain('near(x[1], 0.25) && ((0.25-DOLFIN_EPS < x[0]) && (x[0] < 0.75+DOLFIN_EPS))'),
        4: CompiledSubDomain('near(x[1], 0.75) && ((0.25-DOLFIN_EPS < x[0]) && (x[0] < 0.75+DOLFIN_EPS))')
    }
    
    return {
        'solution': {'uS': to_expr(uS), 'uD': to_expr(uD), 'pS': to_expr(pS), 'pD': to_expr(pD),
                     'lm': PiecewiseExpression(lm_subdomains, dict(enumerate(map(to_expr, lms), 1)))},
        'fS': to_expr(fS),
        'fD': to_expr(fD),
        # Standard boundary data
        'velocity_S': dict(enumerate(map(to_expr, [uS]*len(normalsS)), 1)),
        'traction_S': dict(enumerate(map(to_expr, traction), 1)),
        'pressure_D': dict(enumerate(map(to_expr, [pD]*len(normalsD)), 1)),
        'flux_D': dict(enumerate(map(to_expr, [uD]*len(normalsD)), 1)),
        # Interface boundary conditions
        'g_u': dict(enumerate(map(to_expr, g_u), 1)),
        'g_n': dict(enumerate(map(to_expr, g_n), 1)),
        'g_t': dict(enumerate(map(to_expr, g_t), 1)),
        # Geometry setup
        'get_geometry': immersed_geometry
    }