Beispiel #1
0
def test_physically_mapped_facet():
    mesh = Mesh(VectorElement("P", triangle, 1))

    # set up variational problem
    U = FiniteElement("Morley", mesh.ufl_cell(), 2)
    V = FiniteElement("P", mesh.ufl_cell(), 1)
    R = FiniteElement("P", mesh.ufl_cell(), 1)
    Vv = VectorElement(BrokenElement(V))
    Qhat = VectorElement(BrokenElement(V[facet]))
    Vhat = VectorElement(V[facet])
    Z = FunctionSpace(mesh, MixedElement(U, Vv, Qhat, Vhat, R))

    z = Coefficient(Z)
    u, d, qhat, dhat, lam = split(z)

    s = FacetNormal(mesh)
    trans = as_matrix([[1, 0], [0, 1]])
    mat = trans*grad(grad(u))*trans + outer(d, d) * u
    J = (u**2*dx +
         u**3*dx +
         u**4*dx +
         inner(mat, mat)*dx +
         inner(grad(d), grad(d))*dx +
         dot(s, d)**2*ds)
    L_match = inner(qhat, dhat - d)
    L = J + inner(lam, inner(d, d)-1)*dx + (L_match('+') + L_match('-'))*dS + L_match*ds
    compile_form(L)
Beispiel #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)]]
    )
Beispiel #3
0
def test_matvec(compile_args):
    """Test evaluation of linear rank-0 form.

    Evaluates expression c * A_ij * f_j where c is a Constant,
    A_ij is a user specified constant matrix and f_j is j-th component
    of user specified vector-valued finite element function (in P1 space).

    """
    e = ufl.VectorElement("P", "triangle", 1)
    mesh = ufl.Mesh(e)
    V = ufl.FunctionSpace(mesh, e)
    f = ufl.Coefficient(V)

    a_mat = np.array([[1.0, 2.0], [1.0, 1.0]])
    a = ufl.as_matrix(a_mat)
    expr = ufl.Constant(mesh) * ufl.dot(a, f)

    points = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0]])
    obj, module = ffcx.codegeneration.jit.compile_expressions(
        [(expr, points)], cffi_extra_compile_args=compile_args)

    ffi = cffi.FFI()
    kernel = obj[0][0]

    c_type, np_type = float_to_type("double")

    A = np.zeros((3, 2), dtype=np_type)
    f_mat = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])

    # Coefficient storage XYXYXY
    w = np.array(f_mat.T.flatten(), dtype=np_type)
    c = np.array([0.5], dtype=np_type)

    # Coords storage XYXYXY
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)
    kernel.tabulate_expression(
        ffi.cast('{type} *'.format(type=c_type), A.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data))

    # Check the computation against correct NumPy value
    assert np.allclose(A, 0.5 * np.dot(a_mat, f_mat).T)

    # Prepare NumPy array of points attached to the expression
    length = kernel.num_points * kernel.topological_dimension
    points_kernel = np.frombuffer(
        ffi.buffer(kernel.points, length * ffi.sizeof("double")), np.double)
    points_kernel = points_kernel.reshape(points.shape)
    assert np.allclose(points, points_kernel)

    # Check the value shape attached to the expression
    value_shape = np.frombuffer(
        ffi.buffer(kernel.value_shape,
                   kernel.num_components * ffi.sizeof("int")), np.intc)
    assert np.allclose(expr.ufl_shape, value_shape)
Beispiel #4
0
 def eps(self, u):
     if self.model_type == "2D":
         return ufl.sym(ufl.grad(u))
     if self.model_type == "plane-strain":
         return ufl.sym(
             ufl.as_matrix([
                 [u[0].dx(0), u[0.].dx(1), 0],
                 [u[1].dx(0), u[1].dx(1), 0],
                 [0, 0, 0],
             ]))
def test_invariants_eigenstate(A, squaremesh_5):

    dx = ufl.dx(squaremesh_5)

    A_ = ufl.as_matrix(dolfinx.fem.Constant(squaremesh_5, A))

    [e0, e1, e2], [E0, E1, E2] = dolfiny.invariants.eigenstate(A_)

    e_num = np.sort(np.linalg.eigvals(A))
    e_sym = dolfiny.expression.assemble(ufl.as_vector([e0, e1, e2]), dx)

    assert np.isclose(e_num, e_sym, atol=1e-14).all()

    As = dolfiny.expression.assemble(e0 * E0 + e1 * E1 + e2 * E2, dx)

    assert np.isclose(A, As).all()
Beispiel #6
0
  def solve(self, it=0):
    if self.group_GS:
      self.solve_group_GS(it)
    else:
      super(EllipticSNFluxModule, self).solve(it)
      self.slns_mg = split(self.sln)

    i,p,q,k1,k2 = ufl.indices(5)

    sol_timer = Timer("-- Complete solution")
    aux_timer = Timer("---- SOL: Computing angular flux + adjoint")

    # TODO: Move to Discretization
    V11 = FunctionSpace(self.DD.mesh, "CG", self.DD.parameters["p"])

    for gto in range(self.DD.G):
      self.PD.get_xs('D', self.D, gto)

      form = self.D * ufl.diag_vector(ufl.as_matrix(self.DD.ordinates_matrix[i,p]*self.slns_mg[gto][q].dx(i), (p,q)))

      for gfrom in range(self.DD.G):
        pres_Ss = False

        # TODO: Enlarge self.S and self.C to (L+1)^2 (or 1./2.*(L+1)*(L+2) in 2D) to accomodate for anisotropic
        # scattering (lines below using CC, SS are correct only for L = 0, when the following inner loop runs only
        # once.
        for l in range(self.L+1):
          for m in range(-l, l+1):
            if self.DD.angular_quad.get_D() == 2 and divmod(l+m, 2)[1] == 0:
              continue

            pres_Ss |= self.PD.get_xs('Ss', self.S[l], gto, gfrom, l)
            self.PD.get_xs('C', self.C[l], gto, gfrom, l)

        if pres_Ss:
          Cd = ufl.diag(self.C)
          CC = self.tensors.Y[p,k1] * Cd[k1,k2] * self.tensors.Qt[k2,q,i]

          form += ufl.as_vector(CC[p,q,i] * self.slns_mg[gfrom][q].dx(i), p)

      # project(form, self.DD.Vpsi1, function=self.aux_slng, preconditioner_type="petsc_amg")
      # FASTER, but requires form compilation for each dir.:
      for pp in range(self.DD.M):
        assign(self.aux_slng.sub(pp), project(form[pp], V11, preconditioner_type="petsc_amg"))

      self.psi_mg[gto].assign(self.slns_mg[gto] + self.aux_slng)
      self.adj_psi_mg[gto].assign(self.slns_mg[gto] - self.aux_slng)
Beispiel #7
0
  def __init__(self, problem, SN_order, verbosity=0):
    super(SNDiscretization, self).__init__(problem, verbosity)

    if self.verb > 1: print0("Obtaining angular discretization data")
    t_ordinates = Timer("Angular discretization data")

    from transport_data import ordinates_ext_module, quadrature_file
    from common import check_sn_order

    self.angular_quad = ordinates_ext_module.OrdinatesData(SN_order, self.mesh.topology().dim(), quadrature_file)
    self.M = self.angular_quad.get_M()
    self.N = check_sn_order(SN_order)

    ord_mat = [self.angular_quad.get_xi().tolist(), self.angular_quad.get_eta().tolist()]
    if self.angular_quad.get_D() == 3: ord_mat.append(self.angular_quad.get_mu().tolist())
    self.ordinates_matrix = as_matrix(ord_mat)

    if self.verb > 2:
      self.angular_quad.print_info()
Beispiel #8
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
Beispiel #9
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
Beispiel #10
0
    def __init__(self, Vh, covariance, mean=None):
        """
        Constructor

        Inputs:
        - :code:`Vh`:             Finite element space on which the prior is
                                  defined. Must be the Real space with one global 
                                  degree of freedom
        - :code:`covariance`:     The covariance of the prior. Must be a
                                  :code:`numpy.ndarray` of appropriate size
        - :code:`mean`(optional): Mean of the prior distribution. Must be of
                                  type `dolfin.Vector()`
        """

        self.Vh = Vh

        if Vh.dim() != covariance.shape[0] or Vh.dim() != covariance.shape[1]:
            raise ValueError(
                "Covariance incompatible with Finite Element space")

        if not np.issubdtype(covariance.dtype, np.floating):
            raise TypeError("Covariance matrix must be a float array")

        self.covariance = covariance

        #np.linalg.cholesky automatically provides more error checking,
        #so use those
        self.chol = np.linalg.cholesky(self.covariance)

        self.chol_inv = scila.solve_triangular(self.chol,
                                               np.identity(Vh.dim()),
                                               lower=True)

        self.precision = np.dot(self.chol_inv.T, self.chol_inv)

        trial = dl.TrialFunction(Vh)
        test = dl.TestFunction(Vh)

        domain_measure = dl.assemble(dl.Constant(1.) * ufl.dx(Vh.mesh()))
        domain_measure_inv = dl.Constant(1.0 / domain_measure)

        #Identity mass matrix
        self.M = dl.assemble(domain_measure_inv * ufl.inner(trial, test) *
                             ufl.dx)
        self.Msolver = Operator2Solver(self.M)

        if mean:
            self.mean = mean
        else:
            tmp = dl.Vector()
            self.M.init_vector(tmp, 0)
            tmp.zero()
            self.mean = tmp

        if Vh.dim() == 1:
            trial = ufl.as_matrix([[trial]])
            test = ufl.as_matrix([[test]])

        #Create form matrices
        covariance_op = ufl.as_matrix(list(map(list, self.covariance)))
        precision_op = ufl.as_matrix(list(map(list, self.precision)))
        chol_op = ufl.as_matrix(list(map(list, self.chol)))
        chol_inv_op = ufl.as_matrix(list(map(list, self.chol_inv)))

        #variational for the regularization operator, or the precision matrix
        var_form_R = domain_measure_inv \
                     * ufl.inner(test, ufl.dot(precision_op, trial)) * ufl.dx

        #variational for the inverse regularization operator, or the covariance
        #matrix
        var_form_Rinv = domain_measure_inv \
                        * ufl.inner(test, ufl.dot(covariance_op, trial)) * ufl.dx

        #variational form for the square root of the regularization operator
        var_form_R_sqrt = domain_measure_inv \
                          * ufl.inner(test, ufl.dot(chol_inv_op.T, trial)) * ufl.dx

        #variational form for the square root of the inverse regularization
        #operator
        var_form_Rinv_sqrt = domain_measure_inv \
                             * ufl.inner(test, ufl.dot(chol_op, trial)) * ufl.dx

        self.R = dl.assemble(var_form_R)
        self.RSolverOp = dl.assemble(var_form_Rinv)
        self.Rsolver = Operator2Solver(self.RSolverOp)
        self.sqrtR = dl.assemble(var_form_R_sqrt)
        self.sqrtRinv = dl.assemble(var_form_Rinv_sqrt)
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})