Beispiel #1
0
 def __str__(self):
     "Format as string for pretty printing."
     qs = self.quadrature_scheme()
     qs = "" if qs is None else "(%s)" % qs
     v = self.variant()
     v = "" if v is None else "(%s)" % v
     return "<%s%s%s%s on a %s>" % (self._short_name, istr(
         self.degree()), qs, v, self.cell())
Beispiel #2
0
 def __str__(self):
     "Format as string for pretty printing."
     qs = self.quadrature_scheme()
     qs = "" if qs is None else "(%s)" % qs
     v = self.variant()
     v = "" if v is None else "(%s)" % v
     return "<%s%s%s%s on a %s>" % (self._short_name, istr(self.degree()),
                                    qs, v, self.cell())
Beispiel #3
0
def canonical_element_description(family, cell, order, form_degree):
    """Given basic element information, return corresponding element information on canonical form.

    Input: family, cell, (polynomial) order, form_degree
    Output: family (canonical), short_name (for printing), order, value shape,
    reference value shape, sobolev_space.

    This is used by the FiniteElement constructor to ved input
    data against the element list and aliases defined in ufl.
    """

    # Get domain dimensions
    if cell is not None:
        tdim = cell.topological_dimension()
        gdim = cell.geometric_dimension()
        if isinstance(cell, Cell):
            cellname = cell.cellname()
        else:
            cellname = None
    else:
        tdim = None
        gdim = None
        cellname = None

    # Catch general FEEC notation "P" and "S"
    if form_degree is not None and family in ("P", "S"):
        family, order = feec_element(family, tdim, order, form_degree)

    # Check whether this family is an alias for something else
    while family in aliases:
        if tdim is None:
            error("Need dimension to handle element aliases.")
        (family, order) = aliases[family](family, tdim, order, form_degree)

    # Check that the element family exists
    if family not in ufl_elements:
        error('Unknown finite element "%s".' % family)

    # Check that element data is valid (and also get common family
    # name)
    (family, short_name, value_rank, sobolev_space, mapping, krange, cellnames) = ufl_elements[family]

    # Accept CG/DG on all kind of cells, but use Q/DQ on "product" cells
    if cellname in set(cubes) - set(simplices) or isinstance(cell, TensorProductCell):
        if family == "Lagrange":
            family = "Q"
        elif family == "Discontinuous Lagrange":
            if order >= 1:
                warning("Discontinuous Lagrange element requested on %s, creating DQ element." % cell.cellname())
            family = "DQ"

    # Validate cellname if a valid cell is specified
    if not (cellname is None or cellname in cellnames):
        error('Cellname "%s" invalid for "%s" finite element.' % (cellname, family))

    # Validate order if specified
    if order is not None:
        if krange is None:
            error('Order "%s" invalid for "%s" finite element, '
                  'should be None.' % (order, family))
        kmin, kmax = krange
        if not (kmin is None or (asarray(order) >= kmin).all()):
            error('Order "%s" invalid for "%s" finite element.' %
                  (order, family))
        if not (kmax is None or (asarray(order) <= kmax).all()):
            error('Order "%s" invalid for "%s" finite element.' %
                  (istr(order), family))

    # Override sobolev_space for piecewise constants (TODO: necessary?)
    if order == 0:
        sobolev_space = L2
    if value_rank == 2:
        # Tensor valued fundamental elements in HEin have this shape
        if gdim is None or tdim is None:
            error("Cannot infer shape of element without topological and geometric dimensions.")
        reference_value_shape = (tdim, tdim)
        value_shape = (gdim, gdim)
    elif value_rank == 1:
        # Vector valued fundamental elements in HDiv and HCurl have a shape
        if gdim is None or tdim is None:
            error("Cannot infer shape of element without topological and geometric dimensions.")
        reference_value_shape = (tdim,)
        value_shape = (gdim,)
    elif value_rank == 0:
        # All other elements are scalar values
        reference_value_shape = ()
        value_shape = ()
    else:
        error("Invalid value rank %d." % value_rank)

    return family, short_name, order, value_shape, reference_value_shape, sobolev_space, mapping
Beispiel #4
0
def canonical_element_description(family, cell, order, form_degree):
    """Given basic element information, return corresponding element information on canonical form.

    Input: family, cell, (polynomial) order, form_degree
    Output: family (canonical), short_name (for printing), order, value shape,
    reference value shape, sobolev_space.

    This is used by the FiniteElement constructor to ved input
    data against the element list and aliases defined in ufl.
    """

    # Get domain dimensions
    if cell is not None:
        tdim = cell.topological_dimension()
        gdim = cell.geometric_dimension()
        if isinstance(cell, Cell):
            cellname = cell.cellname()
        else:
            cellname = None
    else:
        tdim = None
        gdim = None
        cellname = None

    # Catch general FEEC notation "P" and "S"
    if form_degree is not None and family in ("P", "S"):
        family, order = feec_element(family, tdim, order, form_degree)

    if form_degree is not None and family in ("P L2", "S L2"):
        family, order = feec_element_l2(family, tdim, order, form_degree)

    # Check whether this family is an alias for something else
    while family in aliases:
        if tdim is None:
            error("Need dimension to handle element aliases.")
        (family, order) = aliases[family](family, tdim, order, form_degree)

    # Check that the element family exists
    if family not in ufl_elements:
        error('Unknown finite element "%s".' % family)

    # Check that element data is valid (and also get common family
    # name)
    (family, short_name, value_rank, sobolev_space, mapping, krange, cellnames) = ufl_elements[family]

    # Accept CG/DG on all kind of cells, but use Q/DQ on "product" cells
    if cellname in set(cubes) - set(simplices) or isinstance(cell, TensorProductCell):
        if family == "Lagrange":
            family = "Q"
        elif family == "Discontinuous Lagrange":
            if order >= 1:
                warning("Discontinuous Lagrange element requested on %s, creating DQ element." % cell.cellname())
            family = "DQ"
        elif family == "Discontinuous Lagrange L2":
            if order >= 1:
                warning("Discontinuous Lagrange L2 element requested on %s, creating DQ L2 element." % cell.cellname())
            family = "DQ L2"

    # Validate cellname if a valid cell is specified
    if not (cellname is None or cellname in cellnames):
        error('Cellname "%s" invalid for "%s" finite element.' % (cellname, family))

    # Validate order if specified
    if order is not None:
        if krange is None:
            error('Order "%s" invalid for "%s" finite element, '
                  'should be None.' % (order, family))
        kmin, kmax = krange
        if not (kmin is None or (asarray(order) >= kmin).all()):
            error('Order "%s" invalid for "%s" finite element.' %
                  (order, family))
        if not (kmax is None or (asarray(order) <= kmax).all()):
            error('Order "%s" invalid for "%s" finite element.' %
                  (istr(order), family))

    # Override sobolev_space for piecewise constants (TODO: necessary?)
    if order == 0:
        sobolev_space = L2
    if value_rank == 2:
        # Tensor valued fundamental elements in HEin have this shape
        if gdim is None or tdim is None:
            error("Cannot infer shape of element without topological and geometric dimensions.")
        reference_value_shape = (tdim, tdim)
        value_shape = (gdim, gdim)
    elif value_rank == 1:
        # Vector valued fundamental elements in HDiv and HCurl have a shape
        if gdim is None or tdim is None:
            error("Cannot infer shape of element without topological and geometric dimensions.")
        reference_value_shape = (tdim,)
        value_shape = (gdim,)
    elif value_rank == 0:
        # All other elements are scalar values
        reference_value_shape = ()
        value_shape = ()
    else:
        error("Invalid value rank %d." % value_rank)

    return family, short_name, order, value_shape, reference_value_shape, sobolev_space, mapping
Beispiel #5
0
 def shortstr(self):
     "Format as string for pretty printing."
     return "%s%s(%s,%s)" % (self._short_name, istr(
         self.degree()), istr(self.quadrature_scheme()), istr(
             self.variant()))
Beispiel #6
0
 def shortstr(self):
     "Format as string for pretty printing."
     return "%s%s(%s,%s)" % (self._short_name, istr(self.degree()),
                             istr(self.quadrature_scheme()), istr(self.variant()))