示例#1
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)]]
    )
示例#2
0
def fenics_cost(u, f):
    x = ufl.SpatialCoordinate(mesh)
    w = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    d = 1 / (2 * ufl.pi ** 2) * w
    alpha = fa.Constant(1e-6)
    J_form = (0.5 * ufl.inner(u - d, u - d)) * ufl.dx + alpha / 2 * f ** 2 * ufl.dx
    J = fa.assemble(J_form)
    return J
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = dolfinx.generation.UnitSquareMesh(dolfinx.MPI.comm_world, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = dolfinx.function.FunctionSpace(mesh, P2)

    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)

    g = -2 + 3.0j
    j = 1.0j

    a_real = inner(u, v) * dx
    L1 = inner(g, v) * dx

    b = dolfinx.fem.assemble_vector(L1)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    bnorm = b.norm(PETSc.NormType.N1)
    b_norm_ref = abs(-2 + 3.0j)
    assert bnorm == pytest.approx(b_norm_ref)

    A = dolfinx.fem.assemble_matrix(a_real)
    A.assemble()
    A0_norm = A.norm(PETSc.NormType.FROBENIUS)

    x = SpatialCoordinate(mesh)

    a_imag = j * inner(u, v) * dx
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = inner(f, v) * dx
    A = dolfinx.fem.assemble_matrix(a_imag)
    A.assemble()
    A1_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A0_norm == pytest.approx(A1_norm)

    b = dolfinx.fem.assemble_vector(L0)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b1_norm = b.norm(PETSc.NormType.N2)

    a_complex = (1 + j) * inner(u, v) * dx
    f = ufl.sin(2 * np.pi * x[0])
    L2 = inner(f, v) * dx
    A = dolfinx.fem.assemble_matrix(a_complex)
    A.assemble()
    A2_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A1_norm == pytest.approx(A2_norm / np.sqrt(2))
    b = dolfinx.fem.assemble_vector(L2)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b2_norm = b.norm(PETSc.NormType.N2)
    assert b2_norm == pytest.approx(b1_norm)
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = create_unit_square(MPI.COMM_WORLD, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = FunctionSpace(mesh, P2)
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    g = -2 + 3.0j
    j = 1.0j

    a_real = form(inner(u, v) * dx)
    L1 = form(inner(g, v) * dx)

    b = assemble_vector(L1)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    bnorm = b.norm(PETSc.NormType.N1)
    b_norm_ref = abs(-2 + 3.0j)
    assert bnorm == pytest.approx(b_norm_ref)

    A = assemble_matrix(a_real)
    A.assemble()
    A0_norm = A.norm(PETSc.NormType.FROBENIUS)

    x = ufl.SpatialCoordinate(mesh)

    a_imag = form(j * inner(u, v) * dx)
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = form(inner(f, v) * dx)
    A = assemble_matrix(a_imag)
    A.assemble()
    A1_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A0_norm == pytest.approx(A1_norm)

    b = assemble_vector(L0)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b1_norm = b.norm(PETSc.NormType.N2)

    a_complex = form((1 + j) * inner(u, v) * dx)
    f = ufl.sin(2 * np.pi * x[0])
    L2 = form(inner(f, v) * dx)
    A = assemble_matrix(a_complex)
    A.assemble()
    A2_norm = A.norm(PETSc.NormType.FROBENIUS)
    assert A1_norm == pytest.approx(A2_norm / np.sqrt(2))
    b = assemble_vector(L2)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    b2_norm = b.norm(PETSc.NormType.N2)
    assert b2_norm == pytest.approx(b1_norm)
示例#5
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
示例#6
0
def test_mpc_assembly(master_point, degree, celltype,
                      get_assemblers):  # noqa: F811

    _, assemble_vector = get_assemblers

    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 3, 5, celltype)
    V = fem.FunctionSpace(mesh, ("Lagrange", degree))

    # Generate reference vector
    v = ufl.TestFunction(V)
    x = ufl.SpatialCoordinate(mesh)
    f = ufl.sin(2 * ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    rhs = ufl.inner(f, v) * ufl.dx
    linear_form = fem.form(rhs)

    def l2b(li):
        return np.array(li, dtype=np.float64).tobytes()

    s_m_c = {
        l2b([1, 0]): {
            l2b([0, 1]): 0.43,
            l2b([1, 1]): 0.11
        },
        l2b([0, 0]): {
            l2b(master_point): 0.69
        }
    }
    mpc = dolfinx_mpc.MultiPointConstraint(V)
    mpc.create_general_constraint(s_m_c)
    mpc.finalize()
    b = assemble_vector(linear_form, mpc)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                  mode=PETSc.ScatterMode.REVERSE)

    # Reduce system with global matrix K after assembly
    L_org = fem.petsc.assemble_vector(linear_form)
    L_org.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES,
                      mode=PETSc.ScatterMode.REVERSE)
    root = 0
    comm = mesh.comm
    with Timer("~TEST: Compare"):
        dolfinx_mpc.utils.compare_mpc_rhs(L_org, b, mpc, root=root)

    list_timings(comm, [TimingType.wall])
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})
示例#8
0
def test_complex_algebra(self):
    z1 = ComplexValue(1j)
    z2 = ComplexValue(1+1j)

    # Remember that ufl.algebra functions return ComplexValues, but ufl.mathfunctions return complex Python scalar
    # Any operations with a ComplexValue and a complex Python scalar promote to ComplexValue
    assert z1*z2 == ComplexValue(-1+1j)
    assert z2/z1 == ComplexValue(1-1j)
    assert pow(z2, z1) == ComplexValue((1+1j)**1j)
    assert sqrt(z2) * as_ufl(1) == ComplexValue(cmath.sqrt(1+1j))
    assert ((sin(z2) + cosh(z2) - atan(z2)) * z1) == ComplexValue((cmath.sin(1+1j) + cmath.cosh(1+1j) - cmath.atan(1+1j))*1j)
    assert (abs(z2) - ln(z2))/exp(z1) == ComplexValue((abs(1+1j) - cmath.log(1+1j))/cmath.exp(1j))
示例#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)"
示例#10
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])"
 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
示例#12
0
def test_estimated_degree():
    cell = ufl.tetrahedron
    mesh = ufl.Mesh(ufl.VectorElement('P', cell, 1))
    V = ufl.FunctionSpace(mesh, ufl.FiniteElement('P', cell, 1))
    f = ufl.Coefficient(V)
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    a = u * v * ufl.tanh(ufl.sqrt(ufl.sinh(f) / ufl.sin(f**f))) * ufl.dx

    handler = MockHandler()
    logger.addHandler(handler)
    with pytest.raises(RuntimeError):
        compile_form(a)
    logger.removeHandler(handler)
示例#13
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)
示例#14
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))"
示例#15
0
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = dolfin.function.functionspace.FunctionSpace(mesh, P2)

    u = dolfin.function.argument.TrialFunction(V)
    v = dolfin.function.argument.TestFunction(V)

    g = dolfin.function.constant.Constant(-2 + 3.0j)
    j = dolfin.function.constant.Constant(1.0j)

    a_real = inner(u, v) * dx
    L1 = inner(g, v) * dx

    bnorm = dolfin.fem.assemble(L1).norm(dolfin.cpp.la.Norm.l1)
    b_norm_ref = abs(-2 + 3.0j)
    assert np.isclose(bnorm, b_norm_ref)
    A0_norm = dolfin.fem.assemble(a_real).norm(dolfin.cpp.la.Norm.frobenius)

    x = dolfin.SpatialCoordinate(mesh)

    a_imag = j * inner(u, v) * dx
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = inner(f, v) * dx
    A1_norm = dolfin.fem.assemble(a_imag).norm(dolfin.cpp.la.Norm.frobenius)
    assert np.isclose(A0_norm, A1_norm)
    b1_norm = dolfin.fem.assemble(L0).norm(dolfin.cpp.la.Norm.l2)

    a_complex = (1 + j) * inner(u, v) * dx
    f = ufl.sin(2 * np.pi * x[0])
    L2 = inner(f, v) * dx
    A2_norm = dolfin.fem.assemble(a_complex).norm(dolfin.cpp.la.Norm.frobenius)
    assert np.isclose(A1_norm, A2_norm / np.sqrt(2))
    b2_norm = dolfin.fem.assemble(L2).norm(dolfin.cpp.la.Norm.l2)
    assert np.isclose(b2_norm, b1_norm)
示例#16
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))))
示例#17
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))"
示例#18
0
def test_latex_formatting_of_derivatives():
    xx = ufl.SpatialCoordinate(ufl.triangle)
    x = xx[0]
    # Test derivatives of basic operators
    assert expr2latex(x.dx(0)) == "1"
    assert expr2latex(x.dx(1)) == "0"
    assert expr2latex(ufl.grad(xx)[0, 0]) == "1"
    assert expr2latex(ufl.grad(xx)[0, 1]) == "0"
    assert expr2latex(ufl.sin(x).dx(0)) == r"\cos(x_0)"

    # Test derivatives of form arguments
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2latex(f.dx(0)) == r"\overset{0}{w}_{, 0}"
    v = ufl.Argument(V, number=3)
    assert expr2latex(v.dx(1)) == r"\overset{3}{v}_{, 1}"
示例#19
0
def test_cpp_formatting_of_derivatives():
    xx = ufl.SpatialCoordinate(ufl.triangle)
    x, y = xx
    # Test derivatives of basic operators
    assert expr2cpp(x.dx(0)) == "1"
    assert expr2cpp(x.dx(1)) == "0"
    assert expr2cpp(ufl.grad(xx)[0, 0]) == "1"
    assert expr2cpp(ufl.grad(xx)[0, 1]) == "0"
    assert expr2cpp(ufl.sin(x).dx(0)) == "cos(x[0])"

    # Test derivatives of target specific test fakes
    V = ufl.FiniteElement("CG", ufl.triangle, 1)
    f = ufl.Coefficient(V, count=0)
    assert expr2cpp(f.dx(0)) == "d1_w0[0]"
    v = ufl.Argument(V, number=3)
    assert expr2cpp(v.dx(1)) == "d1_v3[1]"  # NOT renumbered to 0...
    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)
def test_Dt_linear(V, typ):
    u = Coefficient(V)

    v = TestFunction(V)

    c = Coefficient(V)

    F = (inner(grad(u), grad(v)) + inner(c, v) + inner(Dt(u), v)) * dx

    if typ == "mul":
        F += inner(Dt(u), c) * inner(Dt(u), v) * dx
    elif typ == "div":
        F += inner(Dt(u), v) / Dt(u)[0] * dx
    elif typ == "sin":
        F += inner(sin(Dt(u)[0]), v[0]) * dx

    with pytest.raises(ValueError):
        check_integrals(F.integrals(), expect_time_derivative=True)
示例#22
0
def test_block(V1, V2, squaremesh_5, nest):
    mesh = squaremesh_5

    u0 = dolfinx.Function(V1, name="u0")
    u1 = dolfinx.Function(V2, name="u1")

    v0 = ufl.TestFunction(V1)
    v1 = ufl.TestFunction(V2)

    Phi = (ufl.sin(u0) - 0.5)**2 * ufl.dx(mesh) + (4.0 * u0 -
                                                   u1)**2 * ufl.dx(mesh)

    F0 = ufl.derivative(Phi, u0, v0)
    F1 = ufl.derivative(Phi, u1, v1)

    F = [F0, F1]
    u = [u0, u1]

    opts = PETSc.Options("block")

    opts.setValue('snes_type', 'newtontr')
    opts.setValue('snes_rtol', 1.0e-08)
    opts.setValue('snes_max_it', 12)

    if nest:
        opts.setValue('ksp_type', 'cg')
        opts.setValue('pc_type', 'fieldsplit')
        opts.setValue('fieldsplit_pc_type', 'lu')
        opts.setValue('ksp_rtol', 1.0e-10)
    else:
        opts.setValue('ksp_type', 'preonly')
        opts.setValue('pc_type', 'lu')
        opts.setValue('pc_factor_mat_solver_type', 'mumps')

    problem = dolfiny.snesblockproblem.SNESBlockProblem(F,
                                                        u,
                                                        nest=nest,
                                                        prefix="block")
    sol = problem.solve()

    assert problem.snes.getConvergedReason() > 0
    assert np.isclose((sol[0].vector - np.arcsin(0.5)).norm(), 0.0)
    assert np.isclose((sol[1].vector - 4.0 * np.arcsin(0.5)).norm(), 0.0)
示例#23
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
示例#24
0
def test_monolithic(V1, V2, squaremesh_5):
    mesh = squaremesh_5

    Wel = ufl.MixedElement([V1.ufl_element(), V2.ufl_element()])
    W = dolfinx.FunctionSpace(mesh, Wel)

    u = dolfinx.Function(W)
    u0, u1 = ufl.split(u)

    v = ufl.TestFunction(W)
    v0, v1 = ufl.split(v)

    Phi = (ufl.sin(u0) - 0.5)**2 * ufl.dx(mesh) + (4.0 * u0 -
                                                   u1)**2 * ufl.dx(mesh)

    F = ufl.derivative(Phi, u, v)

    opts = PETSc.Options("monolithic")

    opts.setValue('snes_type', 'newtonls')
    opts.setValue('snes_linesearch_type', 'basic')

    opts.setValue('snes_rtol', 1.0e-10)
    opts.setValue('snes_max_it', 20)

    opts.setValue('ksp_type', 'preonly')
    opts.setValue('pc_type', 'lu')
    opts.setValue('pc_factor_mat_solver_type', 'mumps')

    problem = dolfiny.snesblockproblem.SNESBlockProblem([F], [u],
                                                        prefix="monolithic")
    sol, = problem.solve()

    u0, u1 = sol.split()
    u0 = u0.collapse()
    u1 = u1.collapse()

    assert np.isclose((u0.vector - np.arcsin(0.5)).norm(), 0.0)
    assert np.isclose((u1.vector - 4.0 * np.arcsin(0.5)).norm(), 0.0)
def test_nonlinear_possion(poly_order):
    # Solve a standard Poisson problem with known solution which has
    # rotational symmetry of pi/2 at (x, y) = (0.5, 0.5). Therefore we may
    # impose MPCs on those DoFs which lie on the symmetry plane(s) and test
    # our numerical approximation. We do not impose any constraints at the
    # rotationally degenerate point (x, y) = (0.5, 0.5).

    N_vals = np.array([4, 8, 16], dtype=np.int32)
    l2_error = np.zeros_like(N_vals, dtype=np.double)
    for run_no, N in enumerate(N_vals):
        mesh = dolfinx.mesh.create_unit_square(MPI.COMM_WORLD, N, N)

        V = dolfinx.fem.FunctionSpace(mesh, ("Lagrange", poly_order))

        def boundary(x):
            return np.ones_like(x[0], dtype=np.int8)

        u_bc = dolfinx.fem.Function(V)
        with u_bc.vector.localForm() as u_local:
            u_local.set(0.0)

        facets = dolfinx.mesh.locate_entities_boundary(mesh, 1, boundary)
        topological_dofs = dolfinx.fem.locate_dofs_topological(V, 1, facets)
        zero = np.array(0, dtype=PETSc.ScalarType)
        bc = dolfinx.fem.dirichletbc(zero, topological_dofs, V)
        bcs = [bc]

        # Define variational problem
        u = dolfinx.fem.Function(V)
        v = ufl.TestFunction(V)
        x = ufl.SpatialCoordinate(mesh)

        u_soln = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
        f = -ufl.div((1 + u_soln**2) * ufl.grad(u_soln))

        F = ufl.inner((1 + u**2) * ufl.grad(u), ufl.grad(v)) * ufl.dx \
            - ufl.inner(f, v) * ufl.dx
        J = ufl.derivative(F, u)

        # -- Impose the pi/2 rotational symmetry of the solution as a constraint,
        # -- except at the centre DoF
        def periodic_boundary(x):
            eps = 1e-10
            return np.isclose(x[0], 0.5) & ((x[1] < 0.5 - eps) |
                                            (x[1] > 0.5 + eps))

        def periodic_relation(x):
            out_x = np.zeros(x.shape)
            out_x[0] = x[1]
            out_x[1] = x[0]
            out_x[2] = x[2]
            return out_x

        mpc = dolfinx_mpc.MultiPointConstraint(V)
        mpc.create_periodic_constraint_geometrical(V, periodic_boundary,
                                                   periodic_relation, bcs)
        mpc.finalize()

        # Sanity check that the MPC class has some constraints to impose
        num_slaves_global = mesh.comm.allreduce(len(mpc.slaves), op=MPI.SUM)
        num_masters_global = mesh.comm.allreduce(len(mpc.masters.array),
                                                 op=MPI.SUM)

        assert num_slaves_global > 0
        assert num_masters_global == num_slaves_global

        problem = NonlinearMPCProblem(F, u, mpc, bcs=bcs, J=J)
        solver = NewtonSolverMPC(mesh.comm, problem, mpc)

        # Ensure the solver works with nonzero initial guess
        u.interpolate(lambda x: x[0]**2 * x[1]**2)
        solver.solve(u)

        l2_error_local = dolfinx.fem.assemble_scalar(
            dolfinx.fem.form((u - u_soln)**2 * ufl.dx))
        l2_error_global = mesh.comm.allreduce(l2_error_local, op=MPI.SUM)

        l2_error[run_no] = l2_error_global**0.5

    rates = np.log(l2_error[:-1] / l2_error[1:]) / np.log(2.0)

    assert np.all(rates > poly_order + 0.9)
示例#26
0
# :py:class:`FunctionSpace
# <dolfin.functions.functionspace.FunctionSpace>` ``V``.
#
# Further, the source :math:`f` and the boundary normal derivative
# :math:`g` are involved in the variational forms, and hence we must
# specify these.
#
# With these ingredients, we can write down the bilinear form ``a`` and
# the linear form ``L`` (using UFL operators). In summary, this reads ::

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
x = SpatialCoordinate(mesh)
f = 10 * ufl.exp(-((x[0] - 0.5)**2 + (x[1] - 0.5)**2) / 0.02)
g = ufl.sin(5 * x[0])
a = inner(grad(u), grad(v)) * dx
L = inner(f, v) * dx + inner(g, v) * ds

# Now, we have specified the variational forms and can consider the
# solution of the variational problem. First, we need to define a
# :py:class:`Function <dolfin.functions.function.Function>` ``u`` to
# represent the solution. (Upon initialization, it is simply set to the
# zero function.) A :py:class:`Function
# <dolfin.functions.function.Function>` represents a function living in
# a finite element function space. Next, we can call the :py:func:`solve
# <dolfin.fem.solving.solve>` function with the arguments ``a == L``,
# ``u`` and ``bc`` as follows: ::

# Compute solution
u = Function(V)
示例#27
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
示例#28
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
示例#29
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
示例#30
0
# +
comm = MPI.COMM_SELF
# -

# Create a mesh and function space

msh = mesh.create_rectangle(comm=comm, points=((0.0, 0.0), (2.0, 1.0)), n=(32, 16),
                            cell_type=mesh.CellType.triangle)
V = fem.FunctionSpace(msh, ("Lagrange", 1))

# Define a variartional problem
u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
x = ufl.SpatialCoordinate(msh)
fr = 10 * ufl.exp(-((x[0] - 0.5) ** 2 + (x[1] - 0.5) ** 2) / 0.02)
fc = ufl.sin(2 * np.pi * x[0]) + 10 * ufl.sin(4 * np.pi * x[1]) * 1j
gr = ufl.sin(5 * x[0])
gc = ufl.sin(5 * x[0]) * 1j
a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx
L = ufl.inner(fr + fc, v) * ufl.dx + ufl.inner(gr + gc, v) * ufl.ds


# In preparation for constructing Dirichlet boundary conditions, locate
# facets on the constrained boundary and the corresponding
# degrees-of-freedom
facets = mesh.locate_entities_boundary(msh, dim=1,
                                       marker=lambda x: np.logical_or(np.isclose(x[0], 0.0),
                                                                      np.isclose(x[0], 2.0)))
dofs = fem.locate_dofs_topological(V=V, entity_dim=1, entities=facets)

# 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
示例#32
0
x0 = np.ones(W.dim())

res = minimize(
    min_f,
    x0,
    method="L-BFGS-B",
    jac=True,
    tol=1e-9,
    bounds=((0, 0.8),) * W.dim(),
    options={"gtol": 1e-10, "ftol": 0, "disp": True, "maxiter": 50},
)

# Define the expressions of the analytical solution
alpha = 1e-6
x = ufl.SpatialCoordinate(mesh)
w = ufl.sin(ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
f_analytic = 1 / (1 + alpha * 4 * ufl.pi ** 4) * w
u_analytic = 1 / (2 * ufl.pi ** 2) * f_analytic

f_opt = from_numpy(res.x, fn.Function(W))
u = fn.Function(V)
v = fn.TestFunction(V)
F = (ufl.inner(ufl.grad(u), ufl.grad(v)) - f_opt * v) * ufl.dx
bc = fn.DirichletBC(V, 0.0, "on_boundary")
fn.solve(F == 0, u, bc)
print(f"norm of f_opt is {fn.norm(f_opt)}")

# interpolatation of UFL forms does not work in FEniCS, hence projection
CG3 = fn.FunctionSpace(mesh, "CG", 3)
control_error = fn.errornorm(fn.project(f_analytic, CG3), f_opt)
state_error = fn.errornorm(fn.project(u_analytic, CG3), u)
示例#33
0
# condition.
# <codecell>

from ufl import sin
from dune.ufl import DirichletBC
from dune.fem.plotting import plotComponents
from matplotlib import ticker

vecSpace = solutionSpace(gridView, dimRange=2, order=2)
x = SpatialCoordinate(vecSpace)
vec = vecSpace.interpolate([0,0], name='u_h')
uVec,vVec = TrialFunction(vecSpace), TestFunction(vecSpace)
a  = ( inner(grad(uVec), grad(vVec)) + inner(uVec,vVec) ) * dx
f  = ( uVec[0]*(1-uVec[1])*vVec[0] + uVec[1]*(1-uVec[0])*vVec[1] ) * dx
f  = f + uVec[0]*uVec[0] * vVec[1] * ds
bc = DirichletBC(vecSpace,[sin(4*(x[0]+x[1])),None])
vecScheme = solutionScheme( [a == f, bc],
        parameters={"newton.linear.tolerance": 1e-9} )
vecScheme.solve(target=vec)
plotComponents(vec, gridLines=None, level=2,
               colorbar={"orientation":"horizontal", "ticks":ticker.MaxNLocator(nbins=4)})

# <markdowncell>
# To prescribe $u_2=0$ at the bottom boundary is also straightforward
# <codecell>

bcBottom = DirichletBC(vecSpace,[sin(4*(x[0]+x[1])),0],x[1]<1e-10)
vecScheme = solutionScheme( [a == f, bc, bcBottom],
        parameters={"newton.linear.tolerance": 1e-9} )
vecScheme.solve(target=vec)
plotComponents(vec, gridLines=None, level=2,
示例#34
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()
示例#35
0
def test_pipeline(u_from_mpc):

    # Create mesh and function space
    mesh = create_unit_square(MPI.COMM_WORLD, 5, 5)
    V = fem.FunctionSpace(mesh, ("Lagrange", 1))

    # Solve Problem without MPC for reference
    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)
    d = fem.Constant(mesh, PETSc.ScalarType(0.01))
    x = ufl.SpatialCoordinate(mesh)
    f = ufl.sin(2 * ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1])
    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx - d * ufl.inner(u, v) * ufl.dx
    rhs = ufl.inner(f, v) * ufl.dx
    bilinear_form = fem.form(a)
    linear_form = fem.form(rhs)

    # Generate reference matrices
    A_org = fem.petsc.assemble_matrix(bilinear_form)
    A_org.assemble()
    L_org = fem.petsc.assemble_vector(linear_form)
    L_org.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)

    # Create multipoint constraint
    def periodic_relation(x):
        out_x = np.copy(x)
        out_x[0] = 1 - x[0]
        return out_x

    def PeriodicBoundary(x):
        return np.isclose(x[0], 1)

    facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, PeriodicBoundary)
    arg_sort = np.argsort(facets)
    mt = meshtags(mesh, mesh.topology.dim - 1, facets[arg_sort], np.full(len(facets), 2, dtype=np.int32))

    mpc = dolfinx_mpc.MultiPointConstraint(V)
    mpc.create_periodic_constraint_topological(V, mt, 2, periodic_relation, [], 1)
    mpc.finalize()

    if u_from_mpc:
        uh = fem.Function(mpc.function_space)
        problem = dolfinx_mpc.LinearProblem(bilinear_form, linear_form, mpc, bcs=[], u=uh,
                                            petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
        problem.solve()

        root = 0
        dolfinx_mpc.utils.compare_mpc_lhs(A_org, problem.A, mpc, root=root)
        dolfinx_mpc.utils.compare_mpc_rhs(L_org, problem.b, mpc, root=root)

        # Gather LHS, RHS and solution on one process
        A_csr = dolfinx_mpc.utils.gather_PETScMatrix(A_org, root=root)
        K = dolfinx_mpc.utils.gather_transformation_matrix(mpc, root=root)
        L_np = dolfinx_mpc.utils.gather_PETScVector(L_org, root=root)
        u_mpc = dolfinx_mpc.utils.gather_PETScVector(uh.vector, root=root)

        if MPI.COMM_WORLD.rank == root:
            KTAK = K.T * A_csr * K
            reduced_L = K.T @ L_np
            # Solve linear system
            d = scipy.sparse.linalg.spsolve(KTAK, reduced_L)
            # Back substitution to full solution vector
            uh_numpy = K @ d
            assert np.allclose(uh_numpy, u_mpc)

    else:
        uh = fem.Function(V)
        with pytest.raises(ValueError):
            problem = dolfinx_mpc.LinearProblem(bilinear_form, linear_form, mpc, bcs=[], u=uh,
                                                petsc_options={"ksp_type": "preonly", "pc_type": "lu"})
            problem.solve()
# Interpolate curvature tensor
dolfiny.interpolation.interpolate(B0, B0i)
# ----------------------------------------------------------------------------

# DERIVATIVE with respect to arc-length coordinate s of straight reference configuration: du/ds = du/dx * dx/dr * dr/ds
GRAD = lambda u: ufl.dot(ufl.grad(
    u), J0[:, 0]) * 1 / ufl.geometry.JacobianDeterminant(mesh)  # noqa: E731

# 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)  # noqa: E201
λξ = (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)  # noqa: E201
# Deformed configuration: curvature
κ = GRAD(r)

# Reissner strains (total): determined by deformation kinematics
ε_total = λs - λ0
γ_total = λξ
κ_total = κ

# Reissner strains (elastic): e_total = e_elast + e_presc
ε = ε_elast = ε_total
γ = γ_elast = γ_total
κ = κ_elast = κ_total
示例#37
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
def demo_periodic3D(celltype: CellType):
    # Create mesh and finite element
    if celltype == CellType.tetrahedron:
        # Tet setup
        N = 10
        mesh = create_unit_cube(MPI.COMM_WORLD, N, N, N)
        V = fem.VectorFunctionSpace(mesh, ("CG", 1))
    else:
        # Hex setup
        N = 10
        mesh = create_unit_cube(MPI.COMM_WORLD, N, N, N, CellType.hexahedron)
        V = fem.VectorFunctionSpace(mesh, ("CG", 2))

    def dirichletboundary(x: NDArray[np.float64]) -> NDArray[np.bool_]:
        return np.logical_or(
            np.logical_or(np.isclose(x[1], 0), np.isclose(x[1], 1)),
            np.logical_or(np.isclose(x[2], 0), np.isclose(x[2], 1)))

    # Create Dirichlet boundary condition
    zero = PETSc.ScalarType([0, 0, 0])
    geometrical_dofs = fem.locate_dofs_geometrical(V, dirichletboundary)
    bc = fem.dirichletbc(zero, geometrical_dofs, V)
    bcs = [bc]

    def PeriodicBoundary(x):
        return np.isclose(x[0], 1)

    facets = locate_entities_boundary(mesh, mesh.topology.dim - 1,
                                      PeriodicBoundary)
    arg_sort = np.argsort(facets)
    mt = meshtags(mesh, mesh.topology.dim - 1, facets[arg_sort],
                  np.full(len(facets), 2, dtype=np.int32))

    def periodic_relation(x):
        out_x = np.zeros(x.shape)
        out_x[0] = 1 - x[0]
        out_x[1] = x[1]
        out_x[2] = x[2]
        return out_x

    with Timer("~~Periodic: Compute mpc condition"):
        mpc = dolfinx_mpc.MultiPointConstraint(V)
        mpc.create_periodic_constraint_topological(V.sub(0), mt, 2,
                                                   periodic_relation, bcs, 1)
        mpc.finalize()
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    a = inner(grad(u), grad(v)) * dx

    x = SpatialCoordinate(mesh)
    dx_ = x[0] - 0.9
    dy_ = x[1] - 0.5
    dz_ = x[2] - 0.1
    f = as_vector((x[0] * sin(5.0 * pi * x[1]) +
                   1.0 * exp(-(dx_ * dx_ + dy_ * dy_ + dz_ * dz_) / 0.02),
                   0.1 * dx_ * dz_, 0.1 * dx_ * dy_))

    rhs = inner(f, v) * dx

    petsc_options: Dict[str, Union[str, float, int]]
    if complex_mode:
        rtol = 1e-16
        petsc_options = {"ksp_type": "preonly", "pc_type": "lu"}
    else:
        rtol = 1e-8
        petsc_options = {
            "ksp_type": "cg",
            "ksp_rtol": rtol,
            "pc_type": "hypre",
            "pc_hypre_typ": "boomeramg",
            "pc_hypre_boomeramg_max_iter": 1,
            "pc_hypre_boomeramg_cycle_type": "v",
            "pc_hypre_boomeramg_print_statistics": 1
        }
    problem = LinearProblem(a, rhs, mpc, bcs, petsc_options=petsc_options)
    u_h = problem.solve()

    # --------------------VERIFICATION-------------------------
    print("----Verification----")
    u_ = fem.Function(V)
    u_.x.array[:] = 0
    org_problem = fem.petsc.LinearProblem(a,
                                          rhs,
                                          u=u_,
                                          bcs=bcs,
                                          petsc_options=petsc_options)
    with Timer("~Periodic: Unconstrained solve"):
        org_problem.solve()
        it = org_problem.solver.getIterationNumber()
    print(f"Unconstrained solver iterations: {it}")

    # Write solutions to file
    ext = "tet" if celltype == CellType.tetrahedron else "hex"
    u_.name = "u_" + ext + "_unconstrained"

    # NOTE: Workaround as tabulate dof coordinates does not like extra ghosts
    u_out = fem.Function(V)
    old_local = u_out.x.map.size_local * u_out.x.bs
    old_ghosts = u_out.x.map.num_ghosts * u_out.x.bs
    mpc_local = u_h.x.map.size_local * u_h.x.bs
    assert (old_local == mpc_local)
    u_out.x.array[:old_local + old_ghosts] = u_h.x.array[:mpc_local +
                                                         old_ghosts]
    u_out.name = "u_" + ext
    fname = f"results/demo_periodic3d_{ext}.bp"
    out_periodic = VTXWriter(MPI.COMM_WORLD, fname, u_out)
    out_periodic.write(0)
    out_periodic.close()

    root = 0
    with Timer("~Demo: Verification"):
        dolfinx_mpc.utils.compare_mpc_lhs(org_problem.A,
                                          problem.A,
                                          mpc,
                                          root=root)
        dolfinx_mpc.utils.compare_mpc_rhs(org_problem.b,
                                          problem.b,
                                          mpc,
                                          root=root)

        # Gather LHS, RHS and solution on one process
        A_csr = dolfinx_mpc.utils.gather_PETScMatrix(org_problem.A, root=root)
        K = dolfinx_mpc.utils.gather_transformation_matrix(mpc, root=root)
        L_np = dolfinx_mpc.utils.gather_PETScVector(org_problem.b, root=root)
        u_mpc = dolfinx_mpc.utils.gather_PETScVector(u_h.vector, root=root)

        if MPI.COMM_WORLD.rank == root:
            KTAK = K.T * A_csr * K
            reduced_L = K.T @ L_np
            # Solve linear system
            d = scipy.sparse.linalg.spsolve(KTAK, reduced_L)
            # Back substitution to full solution vector
            uh_numpy = K @ d
            assert np.allclose(uh_numpy, u_mpc, rtol=rtol)
示例#39
0
def compute(space, epsilon, weakBnd, skeleton, mol=None):
    u = TrialFunction(space)
    v = TestFunction(space)
    n = FacetNormal(space)
    he = avg(CellVolume(space)) / FacetArea(space)
    hbnd = CellVolume(space) / FacetArea(space)
    x = SpatialCoordinate(space)

    exact = uflFunction(space.gridView,
                        name="exact",
                        order=3,
                        ufl=sin(x[0] * x[1]))
    uh = space.interpolate(exact, name="solution")

    # diffusion factor
    eps = Constant(epsilon, "eps")
    # transport direction and upwind flux
    b = as_vector([1, 0])
    hatb = (dot(b, n) + abs(dot(b, n))) / 2.0
    # characteristic function for left/right boundary
    dD = conditional((1 + x[0]) * (1 - x[0]) < 1e-10, 1, 0)
    # penalty parameter
    beta = Constant(20 * space.order**2, "beta")

    rhs = -(div(eps * grad(exact) - b * exact)) * v * dx
    aInternal = dot(eps * grad(u) - b * u, grad(v)) * dx
    aInternal -= eps * dot(grad(exact), n) * v * (1 - dD) * ds

    diffSkeleton  = eps*beta/he*jump(u)*jump(v)*dS -\
                    eps*dot(avg(grad(u)),n('+'))*jump(v)*dS -\
                    eps*jump(u)*dot(avg(grad(v)),n('+'))*dS
    if weakBnd:
        diffSkeleton += eps*beta/hbnd*(u-exact)*v*dD*ds -\
                        eps*dot(grad(exact),n)*v*dD*ds
    advSkeleton = jump(hatb * u) * jump(v) * dS
    if weakBnd:
        advSkeleton += (hatb * u + (dot(b, n) - hatb) * exact) * v * dD * ds

    if skeleton:
        form = aInternal + diffSkeleton + advSkeleton
    else:
        form = aInternal

    if weakBnd and skeleton:
        strongBC = None
    else:
        strongBC = DirichletBC(space, exact, dD)

    if space.storage[0] == "numpy":
        solver = {
            "solver": ("suitesparse", "umfpack"),
            "parameters": {
                "newton.verbose": True,
                "newton.linear.verbose": False,
                "newton.linear.tolerance": 1e-5,
            }
        }
    else:
        solver = {
            "solver": "bicgstab",
            "parameters": {
                "newton.linear.preconditioning.method": "ilu",
                "newton.linear.tolerance": 1e-13,
                "newton.verbose": True,
                "newton.linear.verbose": False
            }
        }
    if mol == 'mol':
        scheme = molSolutionScheme([form == rhs, strongBC], **solver)
    else:
        scheme = solutionScheme([form == rhs, strongBC], **solver)

    eoc = []
    info = scheme.solve(target=uh)

    error = dot(uh - exact, uh - exact)
    error0 = math.sqrt(integrate(gridView, error, order=5))
    print(error0, " # output", flush=True)
    for i in range(3):
        gridView.hierarchicalGrid.globalRefine(1)
        uh.interpolate(exact)
        scheme.solve(target=uh)
        error = dot(uh - exact, uh - exact)
        error1 = math.sqrt(integrate(gridView, error, order=5))
        eoc += [math.log(error1 / error0) / math.log(0.5)]
        print(i, error0, error1, eoc, " # output", flush=True)
        error0 = error1

    # print(space.order,epsilon,eoc)
    if (eoc[-1] - (space.order + 1)) < -0.1:
        print("ERROR:", space.order, epsilon, eoc)
    return eoc