Ejemplo n.º 1
0
    def g(self, lam):

        amp_min = self.params['amp_min']
        amp_max = self.params['amp_max']

        lam_threslo = self.params['lam_threslo']
        lam_maxlo = self.params['lam_maxlo']

        lam_threshi = self.params['lam_threshi']
        lam_maxhi = self.params['lam_maxhi']

        # Diss Hirschvogel eq. 2.107
        # TeX: g(\lambda_{\mathrm{myo}}) = \begin{cases} a_{\mathrm{min}}, & \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}}, \\ a_{\mathrm{min}}+\frac{1}{2}\left(a_{\mathrm{max}}-a_{\mathrm{min}}\right)\left(1-\cos \frac{\pi(\lambda_{\mathrm{myo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}})}{\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}}}\right), &  \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,lo}} \leq \lambda_{\mathrm{myo}}  \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}}, \\ a_{\mathrm{max}}, &  \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,lo}} \leq \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}}, \\ a_{\mathrm{min}}+\frac{1}{2}\left(a_{\mathrm{max}}-a_{\mathrm{min}}\right)\left(1-\cos \frac{\pi(\lambda_{\mathrm{myo}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}})}{\hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}}-\hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}}}\right), & \hat{\lambda}_{\mathrm{myo}}^{\mathrm{thres,hi}} \leq \lambda_{\mathrm{myo}} \leq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}}, \\ a_{\mathrm{min}}, & \lambda_{\mathrm{myo}} \geq \hat{\lambda}_{\mathrm{myo}}^{\mathrm{max,hi}} \end{cases}

        return conditional(
            le(lam, lam_threslo), amp_min,
            conditional(
                And(ge(lam, lam_threslo), le(lam, lam_maxlo)), amp_min + 0.5 *
                (amp_max - amp_min) * (1. - cos(pi * (lam - lam_threslo) /
                                                (lam_maxlo - lam_threslo))),
                conditional(
                    And(ge(lam, lam_maxlo), le(lam, lam_threshi)), amp_max,
                    conditional(
                        And(ge(lam, lam_threshi), le(lam, lam_maxhi)),
                        amp_min + 0.5 * (amp_max - amp_min) *
                        (1. - cos(pi * (lam - lam_maxhi) /
                                  (lam_maxhi - lam_threshi))),
                        conditional(ge(lam, lam_maxhi), amp_min, as_ufl(0))))))
Ejemplo n.º 2
0
def rotation_matrix_2d(angle):
    """
    Rotation matrix associated with some
    ``angle``, as a UFL matrix.
    """
    return ufl.as_matrix(
        [[ufl.cos(angle), -ufl.sin(angle)], [ufl.sin(angle), ufl.cos(angle)]]
    )
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions

    """

    degree = 3
    mesh = dolfinx.generation.UnitSquareMesh(dolfinx.MPI.comm_world, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = dolfinx.function.FunctionSpace(mesh, P)

    x = SpatialCoordinate(mesh)

    # Define source term
    A = 1.0 + 2.0 * (2.0 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    C = 1.0 + 1.0j
    a = C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx
    L = inner(f, v) * dx

    # Assemble
    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    b = dolfinx.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    # Create solver
    solver = PETSc.KSP().create(mesh.mpi_comm())
    solver.setOptionsPrefix("test_lu_")
    opts = PETSc.Options("test_lu_")
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    solver.setFromOptions()
    x = A.createVecRight()
    solver.setOperators(A)
    solver.solve(b, x)

    # Reference Solution
    def ref_eval(x):
        return np.cos(2 * np.pi * x[0]) * np.cos(2 * np.pi * x[1])

    u_ref = dolfinx.function.Function(V)
    u_ref.interpolate(ref_eval)

    diff = (x - u_ref.vector).norm(PETSc.NormType.N2)
    assert diff == pytest.approx(0.0, abs=1e-1)
Ejemplo n.º 4
0
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions

    """

    degree = 3
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = dolfin.functionspace.FunctionSpace(mesh, P)

    x = SpatialCoordinate(mesh)

    # Define source term
    A = 1 + 2 * (2 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u = dolfin.function.TrialFunction(V)
    v = dolfin.function.TestFunction(V)
    C = 1 + 1j
    a = C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx
    L = inner(f, v) * dx

    # Assemble
    A = dolfin.fem.assemble_matrix(a)
    A.assemble()
    b = dolfin.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    # Create solver
    solver = PETSc.KSP().create(mesh.mpi_comm())
    opts = PETSc.Options()
    opts["ksp_type"] = "preonly"
    opts["pc_type"] = "lu"
    solver.setFromOptions()
    x = A.createVecRight()
    solver.setOperators(A)
    solver.solve(b, x)

    # Reference Solution
    def ref_eval(values, x):
        values[:,
               0] = np.cos(2 * np.pi * x[:, 0]) * np.cos(2 * np.pi * x[:, 1])

    u_ref = dolfin.interpolate(ref_eval, V)

    xnorm = x.norm(PETSc.NormType.N2)
    x_ref_norm = u_ref.vector.norm(PETSc.NormType.N2)
    assert np.isclose(xnorm, x_ref_norm)
Ejemplo n.º 5
0
def eigenstate_legacy(A):
    """Eigenvalues and eigenprojectors of the 3x3 (real-valued) tensor A.
    Provides the spectral decomposition A = sum_{a=0}^{2} λ_a * E_a
    with eigenvalues λ_a and their associated eigenprojectors E_a = n_a^R x n_a^L
    ordered by magnitude.
    The eigenprojectors of eigenvalues with multiplicity n are returned as 1/n-fold projector.

    Note: Tensor A must not have complex eigenvalues!
    """
    if ufl.shape(A) != (3, 3):
        raise RuntimeError(
            f"Tensor A of shape {ufl.shape(A)} != (3, 3) is not supported!")
    #
    eps = 1.0e-10
    #
    A = ufl.variable(A)
    #
    # --- determine eigenvalues λ0, λ1, λ2
    #
    # additively decompose: A = tr(A) / 3 * I + dev(A) = q * I + B
    q = ufl.tr(A) / 3
    B = A - q * ufl.Identity(3)
    # observe: det(λI - A) = 0  with shift  λ = q + ω --> det(ωI - B) = 0 = ω**3 - j * ω - b
    j = ufl.tr(
        B * B
    ) / 2  # == -I2(B) for trace-free B, j < 0 indicates A has complex eigenvalues
    b = ufl.tr(B * B * B) / 3  # == I3(B) for trace-free B
    # solve: 0 = ω**3 - j * ω - b  by substitution  ω = p * cos(phi)
    #        0 = p**3 * cos**3(phi) - j * p * cos(phi) - b  | * 4 / p**3
    #        0 = 4 * cos**3(phi) - 3 * cos(phi) - 4 * b / p**3  | --> p := sqrt(j * 4 / 3)
    #        0 = cos(3 * phi) - 4 * b / p**3
    #        0 = cos(3 * phi) - r                  with  -1 <= r <= +1
    #    phi_k = [acos(r) + (k + 1) * 2 * pi] / 3  for  k = 0, 1, 2
    p = 2 / ufl.sqrt(3) * ufl.sqrt(j + eps**2)  # eps: MMM
    r = 4 * b / p**3
    r = ufl.Max(ufl.Min(r, +1 - eps), -1 + eps)  # eps: LMM, MMH
    phi = ufl.acos(r) / 3
    # sorted eigenvalues: λ0 <= λ1 <= λ2
    λ0 = q + p * ufl.cos(phi + 2 / 3 * ufl.pi)  # low
    λ1 = q + p * ufl.cos(phi + 4 / 3 * ufl.pi)  # middle
    λ2 = q + p * ufl.cos(phi)  # high
    #
    # --- determine eigenprojectors E0, E1, E2
    #
    E0 = ufl.diff(λ0, A).T
    E1 = ufl.diff(λ1, A).T
    E2 = ufl.diff(λ2, A).T
    #
    return [λ0, λ1, λ2], [E0, E1, E2]
Ejemplo n.º 6
0
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions

    """

    degree = 3
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = dolfin.function.functionspace.FunctionSpace(mesh, P)

    x = dolfin.SpatialCoordinate(mesh)

    # Define source term
    A = 1 + 2 * (2 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u = dolfin.function.argument.TrialFunction(V)
    v = dolfin.function.argument.TestFunction(V)
    C = 1 + 1j
    a = C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx
    L = inner(f, v) * dx

    # Assemble
    A = dolfin.fem.assemble(a)
    b = dolfin.fem.assemble(L)

    # Create solver
    solver = dolfin.cpp.la.PETScKrylovSolver(mesh.mpi_comm())
    dolfin.cpp.la.PETScOptions.set("ksp_type", "preonly")
    dolfin.cpp.la.PETScOptions.set("pc_type", "lu")
    solver.set_from_options()
    x = dolfin.cpp.la.PETScVector()
    solver.set_operator(A)
    solver.solve(x, b)

    # Reference Solution
    @dolfin.function.expression.numba_eval
    def ref_eval(values, x, cell_idx):
        values[:,
               0] = np.cos(2 * np.pi * x[:, 0]) * np.cos(2 * np.pi * x[:, 1])

    u_ref = dolfin.interpolate(dolfin.Expression(ref_eval), V)

    xnorm = x.norm(dolfin.cpp.la.Norm.l2)
    x_ref_norm = u_ref.vector().norm(dolfin.cpp.la.Norm.l2)
    assert np.isclose(xnorm, x_ref_norm)
Ejemplo n.º 7
0
 def assemble_solution(self, t):  # returns
     """
     :param t: time
     :return: Womersley flow (analytic solution) at time t
     analytic solution at any time is a steady parabolic flow + linear combination of 8 modes
     modes were precomputed as 8 functions on given mesh and stored in hdf5 file
     """
     if self.tc is not None:
         self.tc.start('assembleSol')
     sol = Function(self.solutionSpace)
     # analytic solution has zero x and y components
     dofs2 = self.solutionSpace.sub(2).dofmap().dofs(
     )  # gives field of indices corresponding to z axis
     sol.assign(Constant(("0.0", "0.0", "0.0")))  # QQ not needed
     sol.vector()[dofs2] += self.factor * self.bessel_parabolic.vector(
     ).array()  # parabolic part of sol
     for idx in range(8):  # add modes of Womersley sol
         sol.vector()[dofs2] += self.factor * cos(
             self.coefs_exp[idx] * pi *
             t) * self.bessel_real[idx].vector().array()
         sol.vector()[dofs2] += self.factor * -sin(
             self.coefs_exp[idx] * pi *
             t) * self.bessel_complex[idx].vector().array()
     if self.tc is not None:
         self.tc.end('assembleSol')
     return sol
def test_dolfin_expression_compilation_of_math_functions(dolfin):

    # Define some PyDOLFIN coefficients
    mesh = dolfin.UnitSquareMesh(3, 3)
    # Using quadratic element deliberately for accuracy
    V = dolfin.FunctionSpace(mesh, "CG", 2)
    u = dolfin.Function(V)
    u.interpolate(dolfin.Expression("x[0]*x[1]"))
    w0 = u

    # Define ufl expression with math functions
    v = abs(ufl.cos(u))/2 + 0.02
    uexpr = ufl.sin(u) + ufl.tan(v) + ufl.exp(u) + ufl.ln(v) + ufl.atan(v) + ufl.acos(v) + ufl.asin(v)

    #print dolfin.assemble(uexpr**2*dolfin.dx, mesh=mesh) # 11.7846508409

    # Define expected output from compilation
    ucode = 'v_w0[0]'
    vcode = '0.02 + fabs(cos(v_w0[0])) / 2'
    funcs = 'asin(%(v)s) + (acos(%(v)s) + (atan(%(v)s) + (log(%(v)s) + (exp(%(u)s) + (sin(%(u)s) + tan(%(v)s))))))'
    oneliner = funcs % {'u':ucode, 'v':vcode}

    # Oneliner version (ignoring reuse):
    expected_lines = ['double s[1];',
                      'Array<double> v_w0(1);',
                      'w0->eval(v_w0, x);',
                      's[0] = %s;' % oneliner,
                      'values[0] = s[0];']
    #cppcode = format_dolfin_expression(classname="DebugExpression", shape=(), eval_body=expected_lines)
    #print '-'*100
    #print cppcode
    #print '-'*100
    #dolfin.plot(dolfin.Expression(cppcode=cppcode, mesh=mesh))
    #dolfin.interactive()

    # Split version (handles reuse of v, no other reuse):
    expected_lines = ['double s[2];',
                      'Array<double> v_w0(1);',
                      'w0->eval(v_w0, x);',
                      's[0] = %s;' % (vcode,),
                      's[1] = %s;' % (funcs % {'u':ucode,'v':'s[0]'},),
                      'values[0] = s[1];']

    # Define expected evaluation values: [(x,value), (x,value), ...]
    import math
    x, y = 0.6, 0.7
    u = x*y
    v = abs(math.cos(u))/2 + 0.02
    v0 = .52
    expected0 = math.tan(v0) + 1 + math.log(v0) + math.atan(v0) + math.acos(v0) + math.asin(v0)
    expected = math.sin(u) + math.tan(v) + math.exp(u) + math.log(v) + math.atan(v) + math.acos(v) + math.asin(v)
    expected_values = [((0.0, 0.0), (expected0,)),
                       ((x, y), (expected,)),
                       ]

    # Execute all tests
    check_dolfin_expression_compilation(uexpr, expected_lines, expected_values, members={'w0':w0})
Ejemplo n.º 9
0
def test_latex_formatting_of_cmath():
    x = ufl.SpatialCoordinate(ufl.triangle)[0]
    assert expr2latex(ufl.exp(x)) == r"e^{x_0}"
    assert expr2latex(ufl.ln(x)) == r"\ln(x_0)"
    assert expr2latex(ufl.sqrt(x)) == r"\sqrt{x_0}"
    assert expr2latex(abs(x)) == r"\|x_0\|"
    assert expr2latex(ufl.sin(x)) == r"\sin(x_0)"
    assert expr2latex(ufl.cos(x)) == r"\cos(x_0)"
    assert expr2latex(ufl.tan(x)) == r"\tan(x_0)"
    assert expr2latex(ufl.asin(x)) == r"\arcsin(x_0)"
    assert expr2latex(ufl.acos(x)) == r"\arccos(x_0)"
    assert expr2latex(ufl.atan(x)) == r"\arctan(x_0)"
Ejemplo n.º 10
0
def a(phi):
    # phi = 1e5*phi
    n = ufl.grad(phi) / ufl.sqrt(ufl.dot(ufl.grad(phi), ufl.grad(phi)) + 1e-5)

    theta = ufl.atan_2(n[1], n[0])

    n = 1e5 * n + ufl.as_vector([1e-5, 1e-5])
    xx = n[1] / n[0]
    # theta = ufl.asin(xx/ ufl.sqrt(1 + xx**2))
    theta = ufl.atan(xx)

    return 1.0 + epsilon_4 * ufl.cos(m * (theta - theta_0))
Ejemplo n.º 11
0
 def assemble_solution(self, t):  # returns Womersley sol for time t
     if self.tc is not None:
         self.tc.start('assembleSol')
     sol = Function(self.solutionSpace)
     dofs2 = self.solutionSpace.sub(2).dofmap().dofs()  # gives field of indices corresponding to z axis
     sol.assign(Constant(("0.0", "0.0", "0.0")))  # QQ not needed
     sol.vector()[dofs2] += self.factor * self.bessel_parabolic.vector().array()  # parabolic part of sol
     for idx in range(8):  # add modes of Womersley sol
         sol.vector()[dofs2] += self.factor * cos(self.coefs_exp[idx] * pi * t) * self.bessel_real[idx].vector().array()
         sol.vector()[dofs2] += self.factor * -sin(self.coefs_exp[idx] * pi * t) * self.bessel_complex[idx].vector().array()
     if self.tc is not None:
         self.tc.end('assembleSol')
     return sol
Ejemplo n.º 12
0
def test_cpp_formatting_of_cmath():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test cmath functions
    assert expr2cpp(ufl.exp(x)) == "exp(x[0])"
    assert expr2cpp(ufl.ln(x)) == "log(x[0])"
    assert expr2cpp(ufl.sqrt(x)) == "sqrt(x[0])"
    assert expr2cpp(abs(x)) == "fabs(x[0])"
    assert expr2cpp(ufl.sin(x)) == "sin(x[0])"
    assert expr2cpp(ufl.cos(x)) == "cos(x[0])"
    assert expr2cpp(ufl.tan(x)) == "tan(x[0])"
    assert expr2cpp(ufl.asin(x)) == "asin(x[0])"
    assert expr2cpp(ufl.acos(x)) == "acos(x[0])"
    assert expr2cpp(ufl.atan(x)) == "atan(x[0])"
Ejemplo n.º 13
0
def eig(A):
    """Eigenvalues of 3x3 tensor"""
    eps = 1.0e-12

    q = ufl.tr(A) / 3.0
    p1 = 0.5 * (A[0, 1]**2 + A[1, 0]**2 + A[0, 2]**2 + A[2, 0]**2 +
                A[1, 2]**2 + A[2, 1]**2)
    p2 = (A[0, 0] - q)**2 + (A[1, 1] - q)**2 + (A[2, 2] - q)**2 + 2 * p1
    p = ufl.sqrt(p2 / 6)
    B = (A - q * ufl.Identity(3))
    r = ufl.det(B) / (2 * p**3)

    r = ufl.Max(ufl.Min(r, 1.0 - eps), -1.0 + eps)
    phi = ufl.acos(r) / 3.0

    eig0 = ufl.conditional(p2 < eps, q, q + 2 * p * ufl.cos(phi))
    eig2 = ufl.conditional(p2 < eps, q,
                           q + 2 * p * ufl.cos(phi + (2 * numpy.pi / 3)))
    eig1 = ufl.conditional(p2 < eps, q, 3 * q - eig0 -
                           eig2)  # since trace(A) = eig1 + eig2 + eig3

    return eig0, eig1, eig2
Ejemplo n.º 14
0
def test_is_zero_simple_scalar_expressions():
    mesh = UnitSquareMesh(4, 4)
    V = FunctionSpace(mesh, 'CG', 1)
    v = TestFunction(V)
    u = TrialFunction(V)

    check_is_zero(Zero() * u * v, 0)
    check_is_zero(Constant(0) * u * v, 1)
    check_is_zero(Zero() * v, 0)
    check_is_zero(Constant(0) * v, 1)
    check_is_zero(0 * u * v, 0)
    check_is_zero(0 * v, 0)
    check_is_zero(ufl.sin(0) * v, 0)
    check_is_zero(ufl.cos(0) * v, 1)
Ejemplo n.º 15
0
def test_comparison_checker(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 1)

    u = TrialFunction(element)
    v = TestFunction(element)

    a = conditional(ge(abs(u), imag(v)), u, v)
    b = conditional(le(sqrt(abs(u)), imag(v)), as_ufl(1), as_ufl(1j))
    c = conditional(gt(abs(u), pow(imag(v), 0.5)), sin(u), cos(v))
    d = conditional(lt(as_ufl(-1), as_ufl(1)), u, v)
    e = max_value(as_ufl(0), real(u))
    f = min_value(sin(u), cos(v))
    g = min_value(sin(pow(u, 3)), cos(abs(v)))

    assert do_comparison_check(a) == conditional(ge(real(abs(u)), real(imag(v))), u, v)
    with pytest.raises(ComplexComparisonError):
        b = do_comparison_check(b)
    with pytest.raises(ComplexComparisonError):
        c = do_comparison_check(c)
    assert do_comparison_check(d) == conditional(lt(real(as_ufl(-1)), real(as_ufl(1))), u, v)
    assert do_comparison_check(e) == max_value(real(as_ufl(0)), real(real(u)))
    assert do_comparison_check(f) == min_value(real(sin(u)), real(cos(v)))
    assert do_comparison_check(g) == min_value(real(sin(pow(u, 3))), real(cos(abs(v))))
    def __init__(self, mesh, k: int, omega, c, c0, lumped):
        P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), k)
        self.V = FunctionSpace(mesh, P)
        self.u, self.v = Function(self.V), Function(self.V)
        self.g1 = Function(self.V)
        self.g2 = Function(self.V)
        self.omega = omega
        self.c = c
        self.c0 = c0

        n = FacetNormal(mesh)

        # Pieces for plane wave incident field
        x = ufl.geometry.SpatialCoordinate(mesh)
        cos_wave = ufl.cos(self.omega / self.c0 * x[0])
        sin_wave = ufl.sin(self.omega / self.c0 * x[0])

        plane_wave = self.g1 * cos_wave + self.g2 * sin_wave

        dv, p = TrialFunction(self.V), TestFunction(self.V)
        self.L1 = - inner(grad(self.u), grad(p)) * dx(degree=k) \
            - (1 / self.c) * inner(self.v, p) * ds \
            - (1 / self.c**2) * (-self.omega**2) * inner(plane_wave, p) * dx \
            - inner(grad(plane_wave), grad(p)) * dx \
            + inner(dot(grad(plane_wave), n), p) * ds

        # Vector to be re-used for assembly
        self.b = None

        # TODO: precompile/pre-process Form L

        self.lumped = lumped
        if self.lumped:
            a = (1 / self.c**2) * p * dx(degree=k)
            self.M = dolfinx.fem.assemble_vector(a)
            self.M.ghostUpdate(addv=PETSc.InsertMode.ADD,
                               mode=PETSc.ScatterMode.REVERSE)
        else:
            a = (1 / self.c**2) * inner(dv, p) * dx(degree=k)
            M = dolfinx.fem.assemble_matrix(a)
            M.assemble()
            self.solver = PETSc.KSP().create(mesh.mpi_comm())
            opts = PETSc.Options()
            opts["ksp_type"] = "cg"
            opts["ksp_rtol"] = 1.0e-8
            self.solver.setFromOptions()
            self.solver.setOperators(M)
Ejemplo n.º 17
0
 def assemble_solution(self, t):  # returns
     """
     :param t: time
     :return: Womersley flow (analytic solution) at time t
     analytic solution at any time is a steady parabolic flow + linear combination of 8 modes
     modes were precomputed as 8 functions on given mesh and stored in hdf5 file
     """
     if self.tc is not None:
         self.tc.start('assembleSol')
     sol = Function(self.solutionSpace)
     # analytic solution has zero x and y components
     dofs2 = self.solutionSpace.sub(2).dofmap().dofs()  # gives field of indices corresponding to z axis
     sol.assign(Constant(("0.0", "0.0", "0.0")))  # QQ not needed
     sol.vector()[dofs2] += self.factor * self.bessel_parabolic.vector().array()  # parabolic part of sol
     for idx in range(8):  # add modes of Womersley sol
         sol.vector()[dofs2] += self.factor * cos(self.coefs_exp[idx] * pi * t) * self.bessel_real[idx].vector().array()
         sol.vector()[dofs2] += self.factor * -sin(self.coefs_exp[idx] * pi * t) * self.bessel_complex[idx].vector().array()
     if self.tc is not None:
         self.tc.end('assembleSol')
     return sol
Ejemplo n.º 18
0
def test_cpp_formatting_precedence_handling():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test precedence handling with sums
    # Note that the automatic sorting is reflected in formatting!
    assert expr2cpp(y + (2 + x)) == "x[1] + (2 + x[0])"
    assert expr2cpp((x + 2) + y) == "x[1] + (2 + x[0])"

    assert expr2cpp((2 + x) + (3 + y)) == "(2 + x[0]) + (3 + x[1])"

    assert expr2cpp((x + 3) + 2 + y) == "x[1] + (2 + (3 + x[0]))"
    assert expr2cpp(2 + (x + 3) + y) == "x[1] + (2 + (3 + x[0]))"
    assert expr2cpp(2 + (3 + x) + y) == "x[1] + (2 + (3 + x[0]))"
    assert expr2cpp(y + (2 + (3 + x))) == "x[1] + (2 + (3 + x[0]))"

    assert expr2cpp(2 + x + 3 + y) == "x[1] + (3 + (2 + x[0]))"
    assert expr2cpp(2 + x + 3 + y) == "x[1] + (3 + (2 + x[0]))"

    # Test precedence handling with divisions
    # This is more stable than sums since there is no sorting.
    assert expr2cpp((x / 2) / 3) == "(x[0] / 2) / 3"
    assert expr2cpp(x / (y / 3)) == "x[0] / (x[1] / 3)"
    assert expr2cpp((x / 2) / (y / 3)) == "(x[0] / 2) / (x[1] / 3)"
    assert expr2cpp(x / (2 / y) / 3) == "(x[0] / (2 / x[1])) / 3"

    # Test precedence handling with highest level types
    assert expr2cpp(ufl.sin(x)) == "sin(x[0])"
    assert expr2cpp(ufl.cos(x + 2)) == "cos(2 + x[0])"
    assert expr2cpp(ufl.tan(x / 2)) == "tan(x[0] / 2)"
    assert expr2cpp(ufl.acos(x + 3 * y)) == "acos(x[0] + 3 * x[1])"
    assert expr2cpp(ufl.asin(ufl.atan(x**4))) == "asin(atan(pow(x[0], 4)))"
    assert expr2cpp(ufl.sin(y) + ufl.tan(x)) == "sin(x[1]) + tan(x[0])"

    # Test precedence handling with mixed types
    assert expr2cpp(3 * (2 + x)) == "3 * (2 + x[0])"
    assert expr2cpp((2 * x) + (3 * y)) == "2 * x[0] + 3 * x[1]"
    assert expr2cpp(2 * (x + 3) * y) == "x[1] * (2 * (3 + x[0]))"
    assert expr2cpp(2 * (x + 3)**4 * y) == "x[1] * (2 * pow(3 + x[0], 4))"
Ejemplo n.º 19
0
def test_latex_formatting_precedence_handling():
    x, y = ufl.SpatialCoordinate(ufl.triangle)
    # Test precedence handling with sums
    # Note that the automatic sorting is reflected in formatting!
    assert expr2latex(y + (2 + x)) == "x_1 + (2 + x_0)"
    assert expr2latex((x + 2) + y) == "x_1 + (2 + x_0)"

    assert expr2latex((2 + x) + (3 + y)) == "(2 + x_0) + (3 + x_1)"

    assert expr2latex((x + 3) + 2 + y) == "x_1 + (2 + (3 + x_0))"
    assert expr2latex(2 + (x + 3) + y) == "x_1 + (2 + (3 + x_0))"
    assert expr2latex(2 + (3 + x) + y) == "x_1 + (2 + (3 + x_0))"
    assert expr2latex(y + (2 + (3 + x))) == "x_1 + (2 + (3 + x_0))"

    assert expr2latex(2 + x + 3 + y) == "x_1 + (3 + (2 + x_0))"
    assert expr2latex(2 + x + 3 + y) == "x_1 + (3 + (2 + x_0))"

    # Test precedence handling with divisions
    # This is more stable than sums since there is no sorting.
    assert expr2latex((x / 2) / 3) == r"\frac{(\frac{x_0}{2})}{3}"
    assert expr2latex(x / (y / 3)) == r"\frac{x_0}{(\frac{x_1}{3})}"
    assert expr2latex((x / 2) / (y / 3)) == r"\frac{(\frac{x_0}{2})}{(\frac{x_1}{3})}"
    assert expr2latex(x / (2 / y) / 3) == r"\frac{(\frac{x_0}{(\frac{2}{x_1})})}{3}"

    # Test precedence handling with highest level types
    assert expr2latex(ufl.sin(x)) == r"\sin(x_0)"
    assert expr2latex(ufl.cos(x + 2)) == r"\cos(2 + x_0)"
    assert expr2latex(ufl.tan(x / 2)) == r"\tan(\frac{x_0}{2})"
    assert expr2latex(ufl.acos(x + 3 * y)) == r"\arccos(x_0 + 3 x_1)"
    assert expr2latex(ufl.asin(ufl.atan(x**4))) == r"\arcsin(\arctan({x_0}^{4}))"
    assert expr2latex(ufl.sin(y) + ufl.tan(x)) == r"\sin(x_1) + \tan(x_0)"

    # Test precedence handling with mixed types
    assert expr2latex(3 * (2 + x)) == "3 (2 + x_0)"
    assert expr2latex((2 * x) + (3 * y)) == "2 x_0 + 3 x_1"
    assert expr2latex(2 * (x + 3) * y) == "x_1 (2 (3 + x_0))"
Ejemplo n.º 20
0
from __future__ import print_function, division

from ufl import as_vector, dot, grad, cos, pi, SpatialCoordinate, triangle
from dune.grid import structuredGrid, gridFunction
from dune.fem.space import lagrange, combined, product

x = SpatialCoordinate(triangle)
exact = as_vector([cos(2. * pi * x[0]) * cos(2. * pi * x[1]), dot(x, x)])

grid = structuredGrid([0, 0], [1, 1], [16, 16])
spc1 = lagrange(grid, dimRange=1, order=1)
spc2 = lagrange(grid, dimRange=1, order=2)
test1 = spc1.interpolate(exact[0], name="test")
test2 = spc2.interpolate(exact[1], name="test")
spc = combined(spc1, spc2)
solution = spc.interpolate(exact, name="solution")

space = product(spc1, spc2, components=["p", "s"])
df = space.interpolate(exact, name="df")
# print(df.dofVector.size,solution.dofVector.size,
#       df.components[0].dofVector.size,df.p.dofVector.size,test1.dofVector.size)
assert df.components[0].dofVector.size == test1.dofVector.size
assert df.s.dofVector.size == test2.dofVector.size
assert df.dofVector.size == solution.dofVector.size
df.interpolate(solution)
solution.interpolate(df)
test1.interpolate(df.p)
df.s.interpolate(test2)
df.components[0].interpolate(solution[0])
df.p.interpolate(solution[0])
Ejemplo n.º 21
0
from ufl import *

import math
import dune.fem
from dune.fem.function import integrate
import dune.create as create
from dune.ufl import DirichletBC, Space

dimRange = 12  # needs to be >= 4, test with 4,8,11
grid = create.grid("ALUConform", "../data/mixed.dgf", dimgrid=2)

from ufl import SpatialCoordinate
uflSpace = dune.ufl.Space(2, dimRange)
x = SpatialCoordinate(uflSpace.cell())
from math import pi, log, sqrt
from ufl import cos, sin, as_vector
exact = as_vector(
    [sin(3 * pi * x[0]), x[1] * x[1], x[0] *
     x[0], cos(3. * pi * x[1])] + [0] * (dimRange - 4))
v1 = integrate(grid, exact, 5).two_norm

space = create.space("Lagrange", grid, dimRange=dimRange, order=1)
u = space.interpolate(exact, name="u")
v2 = integrate(grid, u, 5).two_norm

print(v1, v2, v1 - v2)
v3 = integrate(grid, inner(grad(u[11]), grad(u[11])), 5)
Ejemplo n.º 22
0
def eigenstate(A):
    """Eigenvalues and eigenprojectors of the 3x3 (real-valued) tensor A.
    Provides the spectral decomposition A = sum_{a=0}^{2} λ_a * E_a
    with (ordered) eigenvalues λ_a and their associated eigenprojectors E_a = n_a^R x n_a^L.

    Note: Tensor A must not have complex eigenvalues!
    """
    if ufl.shape(A) != (3, 3):
        raise RuntimeError(
            f"Tensor A of shape {ufl.shape(A)} != (3, 3) is not supported!")
    #
    eps = 3.0e-16  # slightly above 2**-(53 - 1), see https://en.wikipedia.org/wiki/IEEE_754
    #
    A = ufl.variable(A)
    #
    # --- determine eigenvalues λ0, λ1, λ2
    #
    I1, I2, I3 = invariants_principal(A)
    dq = 2 * I1**3 - 9 * I1 * I2 + 27 * I3
    #
    Δx = [
        A[0, 1] * A[1, 2] * A[2, 0] - A[0, 2] * A[1, 0] * A[2, 1],
        A[0, 1]**2 * A[1, 2] - A[0, 1] * A[0, 2] * A[1, 1] +
        A[0, 1] * A[0, 2] * A[2, 2] - A[0, 2]**2 * A[2, 1],
        A[0, 0] * A[0, 1] * A[2, 1] - A[0, 1]**2 * A[2, 0] -
        A[0, 1] * A[2, 1] * A[2, 2] + A[0, 2] * A[2, 1]**2,
        A[0, 0] * A[0, 2] * A[1, 2] + A[0, 1] * A[1, 2]**2 -
        A[0, 2]**2 * A[1, 0] - A[0, 2] * A[1, 1] * A[1, 2],
        A[0, 0] * A[0, 1] * A[1, 2] - A[0, 1] * A[0, 2] * A[1, 0] -
        A[0, 1] * A[1, 2] * A[2, 2] +
        A[0, 2] * A[1, 2] * A[2, 1],  # noqa: E501
        A[0, 0] * A[0, 2] * A[2, 1] - A[0, 1] * A[0, 2] * A[2, 0] +
        A[0, 1] * A[1, 2] * A[2, 1] -
        A[0, 2] * A[1, 1] * A[2, 1],  # noqa: E501
        A[0, 1] * A[1, 0] * A[1, 2] - A[0, 2] * A[1, 0] * A[1, 1] +
        A[0, 2] * A[1, 0] * A[2, 2] -
        A[0, 2] * A[1, 2] * A[2, 0],  # noqa: E501
        A[0, 0]**2 * A[1, 2] - A[0, 0] * A[0, 2] * A[1, 0] -
        A[0, 0] * A[1, 1] * A[1, 2] - A[0, 0] * A[1, 2] * A[2, 2] +
        A[0, 1] * A[1, 0] * A[1, 2] + A[0, 2] * A[1, 0] * A[2, 2] +
        A[1, 1] * A[1, 2] * A[2, 2] - A[1, 2]**2 * A[2, 1],  # noqa: E501
        A[0, 0]**2 * A[1, 2] - A[0, 0] * A[0, 2] * A[1, 0] -
        A[0, 0] * A[1, 1] * A[1, 2] - A[0, 0] * A[1, 2] * A[2, 2] +
        A[0, 2] * A[1, 0] * A[1, 1] + A[0, 2] * A[1, 2] * A[2, 0] +
        A[1, 1] * A[1, 2] * A[2, 2] - A[1, 2]**2 * A[2, 1],  # noqa: E501
        A[0, 0] * A[0, 1] * A[1, 1] - A[0, 0] * A[0, 1] * A[2, 2] -
        A[0, 1]**2 * A[1, 0] + A[0, 1] * A[0, 2] * A[2, 0] -
        A[0, 1] * A[1, 1] * A[2, 2] + A[0, 1] * A[2, 2]**2 +
        A[0, 2] * A[1, 1] * A[2, 1] -
        A[0, 2] * A[2, 1] * A[2, 2],  # noqa: E501
        A[0, 0] * A[0, 1] * A[1, 1] - A[0, 0] * A[0, 1] * A[2, 2] +
        A[0, 0] * A[0, 2] * A[2, 1] - A[0, 1]**2 * A[1, 0] -
        A[0, 1] * A[1, 1] * A[2, 2] + A[0, 1] * A[1, 2] * A[2, 1] +
        A[0, 1] * A[2, 2]**2 - A[0, 2] * A[2, 1] * A[2, 2],  # noqa: E501
        A[0, 0] * A[0, 1] * A[1, 2] - A[0, 0] * A[0, 2] * A[1, 1] +
        A[0, 0] * A[0, 2] * A[2, 2] - A[0, 1] * A[1, 1] * A[1, 2] -
        A[0, 2]**2 * A[2, 0] + A[0, 2] * A[1, 1]**2 -
        A[0, 2] * A[1, 1] * A[2, 2] +
        A[0, 2] * A[1, 2] * A[2, 1],  # noqa: E501
        A[0, 0] * A[0, 2] * A[1, 1] - A[0, 0] * A[0, 2] * A[2, 2] -
        A[0, 1] * A[0, 2] * A[1, 0] + A[0, 1] * A[1, 1] * A[1, 2] -
        A[0, 1] * A[1, 2] * A[2, 2] + A[0, 2]**2 * A[2, 0] -
        A[0, 2] * A[1, 1]**2 + A[0, 2] * A[1, 1] * A[2, 2],  # noqa: E501
        A[0, 0]**2 * A[1, 1] - A[0, 0]**2 * A[2, 2] -
        A[0, 0] * A[0, 1] * A[1, 0] + A[0, 0] * A[0, 2] * A[2, 0] -
        A[0, 0] * A[1, 1]**2 + A[0, 0] * A[2, 2]**2 +
        A[0, 1] * A[1, 0] * A[1, 1] - A[0, 2] * A[2, 0] * A[2, 2] +
        A[1, 1]**2 * A[2, 2] - A[1, 1] * A[1, 2] * A[2, 1] -
        A[1, 1] * A[2, 2]**2 + A[1, 2] * A[2, 1] * A[2, 2]
    ]  # noqa: E501
    Δy = [
        A[0, 2] * A[1, 0] * A[2, 1] - A[0, 1] * A[1, 2] * A[2, 0],
        A[1, 0]**2 * A[2, 1] - A[1, 0] * A[1, 1] * A[2, 0] +
        A[1, 0] * A[2, 0] * A[2, 2] - A[1, 2] * A[2, 0]**2,
        A[0, 0] * A[1, 0] * A[1, 2] - A[0, 2] * A[1, 0]**2 -
        A[1, 0] * A[1, 2] * A[2, 2] + A[1, 2]**2 * A[2, 0],
        A[0, 0] * A[2, 0] * A[2, 1] - A[0, 1] * A[2, 0]**2 +
        A[1, 0] * A[2, 1]**2 - A[1, 1] * A[2, 0] * A[2, 1],
        A[0, 0] * A[1, 0] * A[2, 1] - A[0, 1] * A[1, 0] * A[2, 0] -
        A[1, 0] * A[2, 1] * A[2, 2] +
        A[1, 2] * A[2, 0] * A[2, 1],  # noqa: E501
        A[0, 0] * A[1, 2] * A[2, 0] - A[0, 2] * A[1, 0] * A[2, 0] +
        A[1, 0] * A[1, 2] * A[2, 1] -
        A[1, 1] * A[1, 2] * A[2, 0],  # noqa: E501
        A[0, 1] * A[1, 0] * A[2, 1] - A[0, 1] * A[1, 1] * A[2, 0] +
        A[0, 1] * A[2, 0] * A[2, 2] -
        A[0, 2] * A[2, 0] * A[2, 1],  # noqa: E501
        A[0, 0]**2 * A[2, 1] - A[0, 0] * A[0, 1] * A[2, 0] -
        A[0, 0] * A[1, 1] * A[2, 1] - A[0, 0] * A[2, 1] * A[2, 2] +
        A[0, 1] * A[1, 0] * A[2, 1] + A[0, 1] * A[2, 0] * A[2, 2] +
        A[1, 1] * A[2, 1] * A[2, 2] - A[1, 2] * A[2, 1]**2,  # noqa: E501
        A[0, 0]**2 * A[2, 1] - A[0, 0] * A[0, 1] * A[2, 0] -
        A[0, 0] * A[1, 1] * A[2, 1] - A[0, 0] * A[2, 1] * A[2, 2] +
        A[0, 1] * A[1, 1] * A[2, 0] + A[0, 2] * A[2, 0] * A[2, 1] +
        A[1, 1] * A[2, 1] * A[2, 2] - A[1, 2] * A[2, 1]**2,  # noqa: E501
        A[0, 0] * A[1, 0] * A[1, 1] - A[0, 0] * A[1, 0] * A[2, 2] -
        A[0, 1] * A[1, 0]**2 + A[0, 2] * A[1, 0] * A[2, 0] -
        A[1, 0] * A[1, 1] * A[2, 2] + A[1, 0] * A[2, 2]**2 +
        A[1, 1] * A[1, 2] * A[2, 0] -
        A[1, 2] * A[2, 0] * A[2, 2],  # noqa: E501
        A[0, 0] * A[1, 0] * A[1, 1] - A[0, 0] * A[1, 0] * A[2, 2] +
        A[0, 0] * A[1, 2] * A[2, 0] - A[0, 1] * A[1, 0]**2 -
        A[1, 0] * A[1, 1] * A[2, 2] + A[1, 0] * A[1, 2] * A[2, 1] +
        A[1, 0] * A[2, 2]**2 - A[1, 2] * A[2, 0] * A[2, 2],  # noqa: E501
        A[0, 0] * A[1, 0] * A[2, 1] - A[0, 0] * A[1, 1] * A[2, 0] +
        A[0, 0] * A[2, 0] * A[2, 2] - A[0, 2] * A[2, 0]**2 -
        A[1, 0] * A[1, 1] * A[2, 1] + A[1, 1]**2 * A[2, 0] -
        A[1, 1] * A[2, 0] * A[2, 2] +
        A[1, 2] * A[2, 0] * A[2, 1],  # noqa: E501
        A[0, 0] * A[1, 1] * A[2, 0] - A[0, 0] * A[2, 0] * A[2, 2] -
        A[0, 1] * A[1, 0] * A[2, 0] + A[0, 2] * A[2, 0]**2 +
        A[1, 0] * A[1, 1] * A[2, 1] - A[1, 0] * A[2, 1] * A[2, 2] -
        A[1, 1]**2 * A[2, 0] + A[1, 1] * A[2, 0] * A[2, 2],  # noqa: E501
        A[0, 0]**2 * A[1, 1] - A[0, 0]**2 * A[2, 2] -
        A[0, 0] * A[0, 1] * A[1, 0] + A[0, 0] * A[0, 2] * A[2, 0] -
        A[0, 0] * A[1, 1]**2 + A[0, 0] * A[2, 2]**2 +
        A[0, 1] * A[1, 0] * A[1, 1] - A[0, 2] * A[2, 0] * A[2, 2] +
        A[1, 1]**2 * A[2, 2] - A[1, 1] * A[1, 2] * A[2, 1] -
        A[1, 1] * A[2, 2]**2 + A[1, 2] * A[2, 1] * A[2, 2]
    ]  # noqa: E501
    Δd = [9, 6, 6, 6, 8, 8, 8, 2, 2, 2, 2, 2, 2, 1]
    Δ = 0
    for i in range(len(Δd)):
        Δ += Δx[i] * Δd[i] * Δy[i]

    Δxp = [
        A[1, 0], A[2, 0], A[2, 1], -A[0, 0] + A[1, 1], -A[0, 0] + A[2, 2],
        -A[1, 1] + A[2, 2]
    ]
    Δyp = [
        A[0, 1], A[0, 2], A[1, 2], -A[0, 0] + A[1, 1], -A[0, 0] + A[2, 2],
        -A[1, 1] + A[2, 2]
    ]
    Δdp = [6, 6, 6, 1, 1, 1]

    dp = 0
    for i in range(len(Δdp)):
        dp += 1 / 2 * Δxp[i] * Δdp[i] * Δyp[i]

    # Avoid dp = 0 and disc = 0, both are known with absolute error of ~eps**2
    # Required to avoid sqrt(0) derivatives and negative square roots
    dp += eps**2
    Δ += eps**2

    phi3 = ufl.atan_2(ufl.sqrt(27) * ufl.sqrt(Δ), dq)

    # sorted eigenvalues: λ0 <= λ1 <= λ2
    λ = [(I1 + 2 * ufl.sqrt(dp) * ufl.cos((phi3 + 2 * ufl.pi * k) / 3)) / 3
         for k in range(1, 4)]
    #
    # --- determine eigenprojectors E0, E1, E2
    #
    E = [ufl.diff(λk, A).T for λk in λ]

    return λ, E
Ejemplo n.º 23
0
def test_div_grad_then_integrate_over_cells_and_boundary():

    # Define 2D geometry
    n = 10
    mesh = RectangleMesh(Point(0.0, 0.0), Point(2.0, 3.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-ffc-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
Ejemplo n.º 24
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-ffc-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 DOLFIN
        # (also passes through form compilation and jit)
        M = f * dx
        f_integral = assemble_scalar(M)  # noqa
        f_integral = MPI.sum(mesh.mpi_comm(), f_integral)

        # Compute integral of f manually from anti-derivative F
        # (passes through PyDOLFIN 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
def CDelta(psi, eps):
    return conditional(lt(abs(psi), eps),
                       1.0 / (2.0 * eps) * (1.0 + ufl.cos(np.pi * psi / eps)),
                       0.0)
Ejemplo n.º 26
0
from dune.fem.view import geometryGridView
from dune.fem.space import lagrange as solutionSpace
from dune.fem.scheme import galerkin as solutionScheme

endTime = 0.05
saveInterval = 0.05

# setup reference surface
referenceView = leafGridView("sphere.dgf", dimgrid=2, dimworld=3)
space = solutionSpace(referenceView, dimRange=referenceView.dimWorld, order=1)

# setup deformed surface
x = ufl.SpatialCoordinate(space)
# positions = space.interpolate(x, name="position")
positions = space.interpolate(
    x * (1 + 0.5 * sin(2 * pi * x[0] * x[1]) * cos(pi * x[2])),
    name="position")
gridView = geometryGridView(positions)
space = solutionSpace(gridView, dimRange=gridView.dimWorld, order=1)

u = ufl.TrialFunction(space)
phi = ufl.TestFunction(space)
dt = dune.ufl.Constant(0.001, "timeStep")
t = dune.ufl.Constant(0.0, "time")

# define storage for discrete solutions
uh = space.interpolate(x, name="uh")
uh_old = uh.copy()

# problem definition
Ejemplo n.º 27
0
from dune.fem.scheme import galerkin as solutionScheme

order = 3
storage = "istl"
# setup reference surface
referenceView = leafGridView("sphere.dgf", dimgrid=2, dimworld=3)
space = solutionSpace(referenceView,
                      dimRange=referenceView.dimWorld,
                      order=order,
                      storage=storage)

# setup deformed surface
x = ufl.SpatialCoordinate(space)
# positions = space.interpolate(x, name="position")
positions = space.interpolate(
    x * (1 + 0.5 * sin(2 * pi * (x[0] + x[1])) * cos(0.25 * pi * x[2])),
    name="position")
gridView = geometryGridView(positions)
space = solutionSpace(gridView,
                      dimRange=gridView.dimWorld,
                      order=order,
                      storage=storage)

u = ufl.TrialFunction(space)
phi = ufl.TestFunction(space)
dt = dune.ufl.Constant(0.01, "timeStep")
t = dune.ufl.Constant(0.0, "time")

# define storage for discrete solutions
uh = space.interpolate(x, name="uh")
uh_old = uh.copy()
# ----------------------------------------------------------------------------

# DERIVATIVE with respect to arc-length coordinate s of straight reference configuration: du/ds = du/dx * dx/dr * dr/ds


def GRAD(u):
    return ufl.dot(ufl.grad(u), J0[:, 0]) * 1 / ufl.geometry.JacobianDeterminant(mesh)


# Undeformed configuration: stretch (at the principal axis)
λ0 = ufl.sqrt(ufl.dot(GRAD(x0), GRAD(x0)))  # from geometry (!= 1)
# Undeformed configuration: curvature
κ0 = -B0i[0, 0]  # from curvature tensor B0i

# Deformed configuration: stretch components (at the principal axis)
λs = (1.0 + GRAD(x0[0]) * GRAD(u) + GRAD(x0[2]) * GRAD(w)) * ufl.cos(r) + \
     (GRAD(x0[2]) * GRAD(u) - GRAD(x0[0]) * GRAD(w)) * ufl.sin(r)
λξ = (1.0 + GRAD(x0[0]) * GRAD(u) + GRAD(x0[2]) * GRAD(w)) * ufl.sin(r) - \
     (GRAD(x0[2]) * GRAD(u) - GRAD(x0[0]) * GRAD(w)) * ufl.cos(r)
# Deformed configuration: curvature
κ = GRAD(r)

# Green-Lagrange strains (total): determined by deformation kinematics
e_total = 1 / 2 * (λs**2 + λξ**2 - λ0**2)
g_total = λξ
k_total = λs * κ + (λs - λ0) * κ0

# Green-Lagrange strains (elastic): e_total = e_elast + e_presc
e = e_elast = e_total
g = g_elast = g_total
k = k_elast = k_total
Ejemplo n.º 29
0
from __future__ import print_function, unicode_literals
import time, math, numpy, ufl
import dune, dune.create
from dune.generator import algorithm

from dune.grid import cartesianDomain, yaspGrid

domain = cartesianDomain([0, 0], [1, 0.25], [12, 3])
yaspView = yaspGrid(domain)

x = ufl.SpatialCoordinate(ufl.triangle)
function = ufl.as_vector([ufl.cos(2 * ufl.pi / (0.3 + x[0] * x[1]))])
# function = dune.create.function("global",gridview=yaspView, name="gl",order=5,
#            value=lambda x: [math.cos(2*math.pi/(0.3+x[0]*x[1]))] )
space = dune.create.space("lagrange", yaspView, order=1, dimRange=1)
uh = space.interpolate(function, name="uh")
error = dune.create.function("ufl",
                             gridView=yaspView,
                             name="error",
                             order=5,
                             ufl=uh - function,
                             virtualize=True)

rules = dune.geometry.quadratureRules(5)

if False:  # dune.fem type grid functions don't yet have vectorization support
    start = time.time()
    l2norm2 = 0
    for e in yaspView.elements:
        hatxs, hatws = rules(e.type).get()
        weights = hatws * e.geometry.integrationElement(hatxs)
Ejemplo n.º 30
0
import pyamg
import ufl
import numpy
import scipy
from minidolfin.meshing import read_meshio, write_meshio
from minidolfin.dofmap import build_dofmap, interpolate_vertex_values
from minidolfin.assembling import assemble
from minidolfin.bcs import build_dirichlet_dofs, bc_apply

mesh = read_meshio('tet_cube.xdmf')

element = ufl.FiniteElement("P", ufl.tetrahedron, 1)
u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
x = ufl.SpatialCoordinate(ufl.tetrahedron)
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = ufl.cos(x[1]) * v * ufl.dx
dofmap = build_dofmap(element, mesh)


def u_bound(x):
    return x[0]


t = time.time()
bc_dofs, bc_vals = build_dirichlet_dofs(dofmap, u_bound)
bc_map = {i: v for i, v in zip(bc_dofs, bc_vals)}
elapsed = time.time() - t
print('BC time = ', elapsed)

t = time.time()
# A, b = symass(dofmap, a, L, bc_map, dtype=numpy.float32)
Ejemplo n.º 31
0
# This example is based on
# http://www.dolfin-adjoint.org/en/latest/documentation/tutorial.html

import firedrake as fd
from firedrake.petsc import PETSc
from firedrake import dmhooks
import ufl
import firedrake_ts

equation = "burgers"  # 'burgers' or 'heat'
n = 50
mesh = fd.UnitSquareMesh(n, n)
V = fd.VectorFunctionSpace(mesh, "CG", 2)

x = ufl.SpatialCoordinate(mesh)
expr = ufl.as_vector([ufl.sin(2 * ufl.pi * x[0]), ufl.cos(2 * ufl.pi * x[1])])
u = fd.interpolate(expr, V)

u_dot = fd.Function(V)
v = fd.TestFunction(V)

nu = fd.Constant(0.0001)  # for burgers
if equation == "heat":
    nu = fd.Constant(0.1)  # for heat

M = fd.derivative(fd.inner(u, v) * fd.dx, u)
R = -(fd.inner(fd.grad(u) * u, v) + nu * fd.inner(fd.grad(u), fd.grad(v))) * fd.dx
if equation == "heat":
    R = -nu * fd.inner(fd.grad(u), fd.grad(v)) * fd.dx
F = fd.action(M, u_dot) - R
Ejemplo n.º 32
0
from __future__ import print_function, division

from ufl import as_vector, grad, cos, pi, SpatialCoordinate, triangle
from dune.grid import structuredGrid, cartesianDomain
from dune.fem.space import lagrange
from dune.alugrid import aluConformGrid as gridManager

grid = gridManager(cartesianDomain([0, 0], [1, 1], [16, 16]))
# grid  = structuredGrid([0, 0], [1, 1], [16, 16])
space = lagrange(grid, dimRange=1, order=1)
x = SpatialCoordinate(triangle)
exact = as_vector([cos(2. * pi * x[0]) * cos(2. * pi * x[1])])
solution = space.interpolate(exact, name="solution")

test = space.interpolate(solution[0], name="tmp")
test = space.interpolate(grad(solution)[0, 0], name="tmp")
dolfiny.interpolation.interpolate(gξ, n0i)
# ----------------------------------------------------------------------------

# Orthogonal projection operator (assumes sufficient geometry approximation)
P = ufl.Identity(mesh.geometry.dim) - ufl.outer(n0i, n0i)

# Thickness variable
X = dolfinx.FunctionSpace(mesh, ("DG", q))
ξ = dolfinx.Function(X, name='ξ')

# Undeformed configuration: director d0 and placement b0
d0 = n0i  # normal of manifold mesh, interpolated
b0 = x0 + ξ * d0

# Deformed configuration: director d and placement b, assumed kinematics, director uses rotation matrix
d = ufl.as_matrix([[ufl.cos(r), 0, ufl.sin(r)], [0, 1, 0],
                   [-ufl.sin(r), 0, ufl.cos(r)]]) * d0
b = x0 + ufl.as_vector([u, 0, w]) + ξ * d

# Configuration gradient, undeformed configuration
J0 = ufl.grad(b0) - ufl.outer(d0, d0)  # = P * ufl.grad(x0) + ufl.grad(ξ * d0)
J0 = ufl.algorithms.apply_algebra_lowering.apply_algebra_lowering(J0)
J0 = ufl.algorithms.apply_derivatives.apply_derivatives(J0)
J0 = ufl.replace(J0, {ufl.grad(ξ): d0})

# Configuration gradient, deformed configuration
J = ufl.grad(b) - ufl.outer(
    d0, d0)  # = P * ufl.grad(x0) + ufl.grad(ufl.as_vector([u, 0, w]) + ξ * d)
J = ufl.algorithms.apply_algebra_lowering.apply_algebra_lowering(J)
J = ufl.algorithms.apply_derivatives.apply_derivatives(J)
J = ufl.replace(J, {ufl.grad(ξ): d0})
Ejemplo n.º 34
0
dt    = dune.ufl.Constant(5e-2, "timeStep")
t     = dune.ufl.Constant(0.0, "time")

# define storage for discrete solutions
uh     = space.interpolate(0, name="uh")
uh_old = uh.copy()

# initial solution
initial = 0

# problem definition

# moving oven
ROven = 0.6
omegaOven = 0.01 * pi * t
P = ufl.as_vector([ROven*cos(omegaOven*t), ROven*sin(omegaOven*t)])
rOven = 0.2
ovenEnergy = 8
chiOven = ufl.conditional(dot(x-P, x-P) < rOven**2, 1, 0)
ovenLoad = ovenEnergy * chiOven

# desk in corner of room
deskCenter = [-0.8, -0.8]
deskSize = 0.2
chiDesk = ufl.conditional(abs(x[0]-deskCenter[0]) < deskSize, 1, 0)\
  * ufl.conditional(abs(x[1] - deskCenter[1]) < deskSize, 1, 0)

# Robin condition for window
windowWidth = 0.5
transmissionCoefficient = 1.2
outerTemperature = -5.0
Ejemplo n.º 35
0
from minidolfin.meshing import read_mesh, write_meshio
from minidolfin.dofmap import build_dofmap, interpolate_vertex_values
from minidolfin.assembling import symass
from minidolfin.bcs import build_dirichlet_dofs
from minidolfin.plot import plot

mesh = read_mesh(
    'https://raw.githubusercontent.com/chrisrichardson/meshdata/master/data/rectangle_mesh.xdmf'
)  # noqa

element = ufl.FiniteElement("P", ufl.triangle, 1)
u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
x = ufl.SpatialCoordinate(ufl.triangle)
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = 50.0 * ufl.cos(6.28 * x[0]) * v * ufl.dx
dofmap = build_dofmap(element, mesh)


def u_bound(x):
    return x[0]


t = time.time()
bc_dofs, bc_vals = build_dirichlet_dofs(dofmap, u_bound, dtype=numpy.float64)
bc_map = {i: v for i, v in zip(bc_dofs, bc_vals)}
elapsed = time.time() - t
print('BC time = ', elapsed)

t = time.time()
A, b = symass(dofmap, a, L, bc_map, dtype=numpy.float64)
Ejemplo n.º 36
0
import ufl
import numpy
from minidolfin.meshing import read_mesh
from minidolfin.dofmap import build_dofmap
from minidolfin.assembling import symass
from minidolfin.bcs import build_dirichlet_dofs

mesh = read_mesh(
    'https://raw.githubusercontent.com/chrisrichardson/meshdata/master/data/rectangle_mesh.xdmf'
)  # noqa

element = ufl.FiniteElement("P", ufl.triangle, 1)
u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
f = ufl.Coefficient(element)
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = ufl.cos(1.0) * v * ufl.dx
dofmap = build_dofmap(element, mesh)


def u_bound(x):
    return x[0]


t = time.time()
bc_dofs, bc_vals = build_dirichlet_dofs(dofmap, u_bound)
bc_map = {i: v for i, v in zip(bc_dofs, bc_vals)}
elapsed = time.time() - t
print('BC time = ', elapsed)

t = time.time()
A, b = symass(dofmap, a, L, bc_map, dtype=numpy.float64)
Ejemplo n.º 37
0
def ode_1st_nonlinear_odeint(a=1.0, b=1.0, c=1.0, nT=10, dt=0.1, **kwargs):
    """
    Create 1st order ODE problem and solve with `ODEInt` time integrator.

    First order nonlinear non-autonomous ODE:
    t * dot u - a * cos(c*t) * u^2 - 2 * u - a * b^2 * t^4 * cos(c*t) = 0 with initial condition u(t=1) = 0
    """

    mesh = UnitCubeMesh(MPI.COMM_WORLD, 1, 1, 1)
    U = FunctionSpace(mesh, ("DG", 0))

    u = Function(U, name="u")
    ut = Function(U, name="ut")

    u.vector.set(0.0)  # initial condition
    ut.vector.set(
        a * b**2 *
        numpy.cos(c))  # exact initial rate of this ODE for generalised alpha

    u.vector.ghostUpdate()
    ut.vector.ghostUpdate()

    δu = ufl.TestFunction(U)

    dx = ufl.Measure("dx", domain=mesh)

    # Global time
    t = dolfinx.Constant(mesh, 1.0)

    # Time step size
    dt = dolfinx.Constant(mesh, dt)

    # Time integrator
    odeint = dolfiny.odeint.ODEInt(t=t, dt=dt, x=u, xt=ut, **kwargs)

    # Weak form (as one-form)
    f = δu * (t * ut - a * ufl.cos(c * t) * u**2 - 2 * u -
              a * b**2 * t**4 * ufl.cos(c * t)) * dx

    # Overall form (as one-form)
    F = odeint.discretise_in_time(f)
    # Overall form (as list of forms)
    F = dolfiny.function.extract_blocks(F, [δu])

    # # Options for PETSc backend
    from petsc4py import PETSc
    opts = PETSc.Options()
    opts["snes_type"] = "newtonls"
    opts["snes_linesearch_type"] = "basic"
    opts["snes_atol"] = 1.0e-10
    opts["snes_rtol"] = 1.0e-12

    # Silence SNES monitoring during test
    dolfiny.snesblockproblem.SNESBlockProblem.print_norms = lambda self, it: 1

    # Create nonlinear problem
    problem = dolfiny.snesblockproblem.SNESBlockProblem(F, [u])

    # Book-keeping of results
    u_avg = numpy.zeros(nT + 1)
    u_avg[0] = u.vector.sum() / u.vector.getSize()

    dolfiny.utils.pprint(f"+++ Processing time steps = {nT}")

    # Process time steps
    for time_step in range(1, nT + 1):

        # Stage next time step
        odeint.stage()

        # Solve nonlinear problem
        u, = problem.solve()

        # Assert convergence of nonlinear solver
        assert problem.snes.getConvergedReason(
        ) > 0, "Nonlinear solver did not converge!"

        # Update solution states for time integration
        odeint.update()

        # Store result
        u_avg[time_step] = u.vector.sum() / u.vector.getSize()

    return u_avg