Esempio n. 1
0
 def diffusion(fce):
     if self.useLaplace:
         return nu * inner(grad(fce), grad(v1)) * dx
     else:
         form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
         if self.bcv == 'CDN':
             return form
         if self.bcv == 'LAP':
             return form - inner(nu * dot(grad(fce).T, n), v1) * problem.get_outflow_measure_form()
         if self.bcv == 'DDN':
             return form  # additional term must be added to non-constant part
Esempio n. 2
0
 def diffusion(fce):
     if self.useLaplace:
         return nu*inner(grad(fce), grad(v1)) * dx
     else:
         form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
         if self.bcv == 'CDN':
             # IMP will work only if p=0 on output, or we must add term
             # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
             return form
         if self.bcv == 'LAP':
             return form - inner(nu*dot(grad(fce).T, n), v1)  * problem.get_outflow_measure_form()
         if self.bcv == 'DDN':
             # IMP will work only if p=0 on output, or we must add term
             # inner(p0*n, v)*problem.get_outflow_measure_form() to avoid boundary layer
             return form  # additional term must be added to non-constant part
Esempio n. 3
0
 def nonlinearity(function):
     if self.use_ema:
        return 2*inner(dot(sym(grad(function)), u_ext), v1) * dx + inner(div(function)*u_ext, v1) * dx
         # return 2*inner(dot(sym(grad(function)), u_ext), v) * dx + inner(div(u_ext)*function, v) * dx
         # QQ implement this way?
     else:
         return inner(dot(grad(function), u_ext), v1) * dx
Esempio n. 4
0
    def compute_functionals(self, velocity, pressure, t):
        if self.args.wss:
            info('Computing stress tensor')
            I = Identity(velocity.geometric_dimension())
            T = TensorFunctionSpace(self.mesh, 'Lagrange', 1)
            stress = project(-pressure*I + 2*sym(grad(velocity)), T)
            info('Generating boundary mesh')
            wall_mesh = BoundaryMesh(self.mesh, 'exterior')
            # wall_mesh = SubMesh(self.mesh, self.facet_function, 1)   # QQ why does not work?
            # plot(wall_mesh, interactive=True)
            info('  Boundary mesh geometric dim: %d' % wall_mesh.geometry().dim())
            info('  Boundary mesh topologic dim: %d' % wall_mesh.topology().dim())
            info('Projecting stress to boundary mesh')
            Tb = TensorFunctionSpace(wall_mesh, 'Lagrange', 1)
            stress_b = interpolate(stress, Tb)
            self.fileDict['wss']['file'] << stress_b


            if False:  # does not work
                info('Computing WSS')
                n = FacetNormal(wall_mesh)
                info(stress_b, True)
                # wss = stress_b*n - inner(stress_b*n, n)*n
                wss = dot(stress_b, n) - inner(dot(stress_b, n), n)*n   # equivalent
                Vb = VectorFunctionSpace(wall_mesh, 'Lagrange', 1)
                Sb = FunctionSpace(wall_mesh, 'Lagrange', 1)
                # wss_func = project(wss, Vb)
                wss_norm = project(sqrt(inner(wss, wss)), Sb)
                plot(wss_norm, interactive=True)
Esempio n. 5
0
    def compute_functionals(self, velocity, pressure, t, step):
        if self.args.wss == 'all' or \
                (step >= self.stepsInCycle and self.args.wss == 'peak' and
                 (self.distance_from_chosen_steps < 0.5 * self.metadata['dt'])):
            # TODO check if choosing time steps works properly
            # QQ might skip step? change 0.5 to 0.51?
            self.tc.start('WSS')
            begin('WSS (%dth step)' % step)
            if self.args.wss_method == 'expression':
                stress = project(self.nu*2*sym(grad(velocity)), self.T)
                # pressure is not used as it contributes only to the normal component
                stress.set_allow_extrapolation(True)   # need because of some inaccuracies in BoundaryMesh coordinates
                stress_b = interpolate(stress, self.Tb)    # restrict stress to boundary mesh
                # self.fileDict['stress']['file'].write(stress_b, self.actual_time)
                # info('Saved stress tensor')
                info('Computing WSS')
                wss = dot(stress_b, self.nb) - inner(dot(stress_b, self.nb), self.nb)*self.nb
                wss_func = project(wss, self.Vb)
                wss_norm = project(sqrt_ufl(inner(wss, wss)), self.Sb)
                info('Saving WSS')
                self.fileDict['wss']['file'].write(wss_func, self.actual_time)
                self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time)
            if self.args.wss_method == 'integral':
                wss_norm = Function(self.SDG)
                mS = TestFunction(self.SDG)
                scaling = 1/FacetArea(self.mesh)
                stress = self.nu*2*sym(grad(velocity))
                wss = dot(stress, self.normal) - inner(dot(stress, self.normal), self.normal)*self.normal
                wss_norm_form = scaling*mS*sqrt_ufl(inner(wss, wss))*ds   # ds is integral over exterior facets only
                assemble(wss_norm_form, tensor=wss_norm.vector())
                self.fileDict['wss_norm']['file'].write(wss_norm, self.actual_time)

                # to get vector WSS values:
                # NT this works, but in ParaView for (DG,1)-vector space glyphs are displayed in cell centers
                # wss_vector = []
                # for i in range(3):
                #     wss_component = Function(self.SDG)
                #     wss_vector_form = scaling*wss[i]*mS*ds
                #     assemble(wss_vector_form, tensor=wss_component.vector())
                #     wss_vector.append(wss_component)
                # wss_func = project(as_vector(wss_vector), self.VDG)
                # self.fileDict['wss']['file'].write(wss_func, self.actual_time)
            self.tc.end('WSS')
            end()
Esempio n. 6
0
 def save_vel(self, is_tent, field, t):
     self.vFunction.assign(field)
     self.fileDict['u2' if is_tent else 'u']['file'] << self.vFunction
     if self.doSaveDiff:
         self.vFunction.assign((1.0 / self.vel_normalization_factor[0]) * (field - self.solution))
         self.fileDict['u2D' if is_tent else 'uD']['file'] << self.vFunction
     if self.args.ldsg:
         # info(div(2.*sym(grad(field))-grad(field)).ufl_shape)
         form = div(2.*sym(grad(field))-grad(field))
         self.pFunction.assign(project(sqrt_ufl(inner(form, form)), self.pSpace))
         self.fileDict['ldsg2' if is_tent else 'ldsg']['file'] << self.pFunction
Esempio n. 7
0
 def eps(v):
     return sym(grad(v))
Esempio n. 8
0
 def sigma(w, gdim):
     return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr(
         grad(w)) * ufl.Identity(gdim)
Esempio n. 9
0
def strain(u):
    return sym(grad(u))
Esempio n. 10
0
def _e(u):
  return ufl.sym(ufl.grad(u))
Esempio n. 11
0
 def sigma(v):
     return (2.0 * mu * ufl.sym(ufl.grad(v))
             + lmbda * ufl.tr(ufl.sym(ufl.grad(v))) * ufl.Identity(len(v)))
Esempio n. 12
0
 def nonlinearity(function):
     if self.args.ema:
         return 2 * inner(dot(sym(grad(function)), u_ext), v1
                          ) * dx + inner(div(function) * u_ext, v1) * dx
     else:
         return inner(dot(grad(function), u_ext), v1) * dx
Esempio n. 13
0
def sym_grad(u: Expr):
    return sym(grad(u))
Esempio n. 14
0
 def T(u):
     return -p * I + 2.0 * nu * sym(grad(u))
Esempio n. 15
0
def symgrad(v):
    return ufl.sym(ufl.nabla_grad(v))
Esempio n. 16
0
def test_diff_then_integrate():

    # Define 1D geometry
    n = 21
    mesh = UnitIntervalMesh(MPI.COMM_WORLD, n)

    # Shift and scale mesh
    x0, x1 = 1.5, 3.14
    mesh.coordinates()[:] *= (x1 - x0)
    mesh.coordinates()[:] += x0

    x = SpatialCoordinate(mesh)[0]
    xs = 0.1 + 0.8 * x / x1  # scaled to be within [0.1,0.9]

    # Define list of expressions to test, and configure
    # accuracies these expressions are known to pass with.
    # The reason some functions are less accurately integrated is
    # likely that the default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([x**x])
    reg([x**(x**2)], 8)
    reg([x**(x**3)], 6)
    reg([x**(x**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    try:
        import scipy
    except ImportError:
        scipy = None

    if hasattr(math, 'erf') or scipy is not None:
        reg([erf(xs)])
    else:
        print(
            "Warning: skipping test of erf, old python version and no scipy.")

    # if 0:
    #     print("Warning: skipping tests of bessel functions, doesn't build on all platforms.")
    # elif scipy is None:
    #     print("Warning: skipping tests of bessel functions, missing scipy.")
    # else:
    #     for nu in (0, 1, 2):
    #         # Many of these are possibly more accurately integrated,
    #         # but 4 covers all and is sufficient for this test
    #         reg([bessel_J(nu, xs), bessel_Y(nu, xs), bessel_I(nu, xs), bessel_K(nu, xs)], 4)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2([xx])
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xx, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    for F, acc in F_list:
        # Apply UFL differentiation
        f = diff(F, SpatialCoordinate(mesh))[..., 0]
        if debug:
            print(F)
            print(x)
            print(f)

        # Apply integration with DOLFINX
        # (also passes through form compilation and jit)
        M = f * dx
        f_integral = assemble_scalar(M)  # noqa
        f_integral = mesh.mpi_comm().allreduce(f_integral, op=MPI.SUM)

        # Compute integral of f manually from anti-derivative F
        # (passes through pybind11 interface and uses UFL evaluation)
        F_diff = F((x1, )) - F((x0, ))

        # Compare results. Using custom relative delta instead
        # of decimal digits here because some numbers are >> 1.
        delta = min(abs(f_integral), abs(F_diff)) * 10**-acc
        assert f_integral - F_diff <= delta
Esempio n. 17
0
def test_div_grad_then_integrate_over_cells_and_boundary():

    # Define 2D geometry
    n = 10
    mesh = RectangleMesh(
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([2.0, 3.0, 0.0])], 2 * n, 3 * n)

    x, y = SpatialCoordinate(mesh)
    xs = 0.1 + 0.8 * x / 2  # scaled to be within [0.1,0.9]
    #    ys = 0.1 + 0.8 * y / 3  # scaled to be within [0.1,0.9]
    n = FacetNormal(mesh)

    # Define list of expressions to test, and configure accuracies
    # these expressions are known to pass with.  The reason some
    # functions are less accurately integrated is likely that the
    # default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([xs**xs])
    reg(
        [xs**(xs**2)], 8
    )  # Note: Accuracies here are from 1D case, not checked against 2D results.
    reg([xs**(xs**3)], 6)
    reg([xs**(xs**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    xxs = as_matrix([[2 * xs**2, 3 * xs**3], [11 * xs**5, 7 * xs**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2(
        [xx]
    )  # TODO: Make unit test for UFL from this, results in listtensor with free indices
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xxs, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    if debug:
        F_list = F_list[1:]

    for F, acc in F_list:
        if debug:
            print('\n', "F:", str(F))

        # Integrate over domain and its boundary
        int_dx = assemble(div(grad(F)) * dx(mesh))  # noqa
        int_ds = assemble(dot(grad(F), n) * ds(mesh))  # noqa

        if debug:
            print(int_dx, int_ds)

        # Compare results. Using custom relative delta instead of
        # decimal digits here because some numbers are >> 1.
        delta = min(abs(int_dx), abs(int_ds)) * 10**-acc
        assert int_dx - int_ds <= delta
 def epsilon(v):
     return sym(grad(v))
Esempio n. 19
0
 def strain(v):
     return ufl.sym(ufl.grad(v))
Esempio n. 20
0
def sym_grad(u: Expr):
    return ufl.sym(ufl.grad(u))
Esempio n. 21
0
def sigma(v):
    return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(grad(v))) * Identity(
        len(v))
Esempio n. 22
0
 def nonlinearity(function):
     if self.args.ema:
         return 2 * inner(dot(sym(grad(function)), u_ext), v1) * dx + inner(div(function) * u_ext, v1) * dx
     else:
         return inner(dot(grad(function), u_ext), v1) * dx
Esempio n. 23
0
 def T(u):
     return -p * I + 2.0 * nu * sym(grad(u))
def σ(v):
    """Return an expression for the stress σ given a displacement field"""
    return 2.0 * μ * ufl.sym(grad(v)) + λ * ufl.tr(ufl.sym(
        grad(v))) * ufl.Identity(len(v))
Esempio n. 25
0
    init_from_file_parameter_scalar_to_tensor(k, "data/het_0.csv")

    T = 500.0
    t = 0.0
    dt = 20.0

    bcd1 = DirichletBC(W.sub(0).sub(0), Constant(0.0), boundaries,
                       1)  # No normal displacement for solid on left side
    bcd3 = DirichletBC(W.sub(0).sub(0), Constant(0.0), boundaries,
                       3)  # No normal displacement for solid on right side
    bcd4 = DirichletBC(W.sub(0).sub(1), Constant(0.0), boundaries,
                       4)  # No normal displacement for solid on bottom side
    bcs = BlockDirichletBC([[bcd1, bcd3, bcd4], []])

    a = inner(2 * mu_l * strain(u) + lmbda_l * div(u) * I, sym(grad(v))) * dx

    b = inner(-alpha * p * I, sym(grad(v))) * dx

    c = rho * alpha * div(u) * q * dx

    d = (rho * ct * p * q * dx +
         dt * dot(rho * k / vis * grad(p), grad(q)) * dx - dt *
         dot(avg_w(rho * k / vis * grad(p), weight_e(k, n)), jump(q, n)) * dS -
         theta * dt *
         dot(avg_w(rho * k / vis * grad(q), weight_e(k, n)), jump(p, n)) * dS +
         dt * penalty1 / h_avg * avg(rho) * k_e(k, n) / avg(vis) *
         dot(jump(p, n), jump(q, n)) * dS -
         dt * dot(rho * k / vis * grad(p), q * n) * ds(2) -
         dt * dot(rho * k / vis * grad(q), p * n) * ds(2) + dt *
         (penalty2 / h * rho / vis * dot(dot(n, k), n) * dot(p * n, q * n)) *
Esempio n. 26
0
def stress_rebar(E, displ):
    return E * D_rebar_map(ufl.sym(ufl.grad(displ)))
 def T(p, v):
     return -p * I + 2.0 * self.nu * sym(grad(v))
 def eps(self, u):
     """Strain tensor as a function of the displacement"""
     return sym(grad(u))