def integrate_rhs(family, degree): power = 5 m = UnitSquareMesh(2**power, 2**power) layers = 10 # Populate the coordinates of the extruded mesh by providing the # coordinates as a field. # TODO: provide a kernel which will describe how coordinates are extruded. mesh = ExtrudedMesh(m, layers, layer_height=0.1) horiz = ufl.FiniteElement(family, "triangle", degree) vert = ufl.FiniteElement(family, "interval", degree) prod = ufl.TensorProductElement(horiz, vert) fs = FunctionSpace(mesh, prod, name="fs") f = Function(fs) populate_p0 = op2.Kernel( """ void populate_tracer(double *x[], double *c[]) { x[0][0] = ((c[1][2] + c[0][2]) / 2); }""", "populate_tracer") coords = f.function_space().mesh().coordinates op2.par_loop(populate_p0, f.cell_set, f.dat(op2.INC, f.cell_node_map()), coords.dat(op2.READ, coords.cell_node_map())) g = assemble(f * dx) return np.abs(g - 0.5)
def __init__(self, element): cell = element.cell() degree = element.degree() family = lambda c: "DG" if c.is_simplex() else "DQ" if isinstance(cell, ufl.TensorProductCell): scalar_element = ufl.TensorProductElement( *(ufl.FiniteElement(family(c), cell=c, degree=d) for (c, d) in zip(cell.sub_cells(), degree))) else: scalar_element = ufl.FiniteElement(family(cell), cell=cell, degree=degree) shape = element.value_shape() if len(shape) == 0: DG = scalar_element elif len(shape) == 1: shape, = shape DG = ufl.VectorElement(scalar_element, dim=shape) else: DG = ufl.TensorElement(scalar_element, shape=shape) self.embedding_element = DG self._V_DG_mass = {} self._DG_inv_mass = {} self._V_approx_inv_mass = {} self._V_inv_mass_ksp = {} self._DG_work = {} self._work_vec = {} self._V_dof_weights = {}
def integrate_rhs(family, degree): power = 5 m = UnitSquareMesh(2 ** power, 2 ** power) layers = 10 # Populate the coordinates of the extruded mesh by providing the # coordinates as a field. # TODO: provide a kernel which will describe how coordinates are extruded. mesh = ExtrudedMesh(m, layers, layer_height=0.1) horiz = ufl.FiniteElement(family, "triangle", degree) vert = ufl.FiniteElement(family, "interval", degree) prod = ufl.TensorProductElement(horiz, vert) fs = FunctionSpace(mesh, prod, name="fs") f = Function(fs) coords = f.function_space().mesh().coordinates domain = "" instructions = """ x[0,0] = 0.5 * (c[1,2] + c[0,2]) """ par_loop((domain, instructions), dx, {'x': (f, INC), 'c': (coords, READ)}, is_loopy_kernel=True, kernel_kwargs={"requires_zeroed_output_arguments": True}) g = assemble(f * dx) return np.abs(g - 0.5)
def make_scalar_element(mesh, family, degree, vfamily, vdegree): """Build a scalar :class:`ufl.FiniteElement`. :arg mesh: The mesh to determine the cell from. :arg family: The finite element family. :arg degree: The degree of the finite element. :arg vfamily: The finite element in the vertical dimension (extruded meshes only). :arg vdegree: The degree of the element in the vertical dimension (extruded meshes only). The ``family`` argument may be an existing :class:`ufl.FiniteElementBase`, in which case all other arguments are ignored and the element is returned immediately. """ if isinstance(family, ufl.FiniteElementBase): return family cell = mesh.ufl_cell() if isinstance(cell, ufl.TensorProductCell) \ and vfamily is not None and vdegree is not None: la = ufl.FiniteElement(family, cell=cell.sub_cells()[0], degree=degree) # If second element was passed in, use it lb = ufl.FiniteElement(vfamily, cell=ufl.interval, degree=vdegree) # Now make the TensorProductElement return ufl.TensorProductElement(la, lb) else: return ufl.FiniteElement(family, cell=cell, degree=degree)
def test_tensor_prod_simple(ufl_A, ufl_B): tensor_ufl = ufl.TensorProductElement(ufl_A, ufl_B) tensor = create_element(tensor_ufl) A = create_element(ufl_A) B = create_element(ufl_B) assert isinstance(tensor, finat.TensorProductElement) assert tensor.factors == (A, B)
def test_tensor_prod_simple(ufl_A, ufl_B): tensor_ufl = ufl.TensorProductElement(ufl_A, ufl_B) tensor = create_element(tensor_ufl) A = create_element(ufl_A) B = create_element(ufl_B) assert isinstance(tensor, FIAT.TensorProductElement) assert tensor.A is A assert tensor.B is B
def test_tensor_prod_simple(ufl_A, ufl_B): tensor_ufl = ufl.TensorProductElement(ufl_A, ufl_B) tensor = create_element(tensor_ufl) A = create_element(ufl_A) B = create_element(ufl_B) assert isinstance(tensor, supported_elements[tensor_ufl.family()]) assert tensor.A is A assert tensor.B is B
def make_scalar_element(mesh, family, degree, vfamily, vdegree): """Build a scalar :class:`ufl.FiniteElement`. :arg mesh: The mesh to determine the cell from. :arg family: The finite element family. :arg degree: The degree of the finite element. :arg vfamily: The finite element in the vertical dimension (extruded meshes only). :arg vdegree: The degree of the element in the vertical dimension (extruded meshes only). The ``family`` argument may be an existing :class:`ufl.FiniteElementBase`, in which case all other arguments are ignored and the element is returned immediately. .. note:: As a side effect, this function finalises the initialisation of the provided mesh, by calling :meth:`.MeshTopology.init` (or :meth:`.MeshGeometry.init`) as appropriate. """ mesh.init() if isinstance(family, ufl.FiniteElementBase): return family topology = mesh.topology cell = topology.ufl_cell() if isinstance(cell, ufl.TensorProductCell) \ and vfamily is not None and vdegree is not None: la = ufl.FiniteElement(family, cell=cell.sub_cells()[0], degree=degree) # If second element was passed in, use it lb = ufl.FiniteElement(vfamily, cell=ufl.interval, degree=vdegree) # Now make the TensorProductElement return ufl.TensorProductElement(la, lb) else: return ufl.FiniteElement(family, cell=cell, degree=degree)
def reconstruct_element(element, cell=None): """Rebuild element with a new cell.""" if cell is None: return element if isinstance(element, ufl.FiniteElement): family = element.family() degree = element.degree() return ufl.FiniteElement(family, cell, degree) if isinstance(element, ufl.VectorElement): sub = reconstruct_element(element.sub_elements()[0], cell=cell) dim = len(element.sub_elements()) return ufl.VectorElement(sub, dim=dim) if isinstance(element, ufl.TensorElement): sub = reconstruct_element(element.sub_elements()[0], cell=cell) shape = element.value_shape() symmetry = element.symmetry() return ufl.TensorElement(sub, shape=shape, symmetry=symmetry) if isinstance(element, ufl.EnrichedElement): eles = [reconstruct_element(e, cell=cell) for e in element._elements] return ufl.EnrichedElement(*eles) if isinstance(element, ufl.RestrictedElement): return ufl.RestrictedElement( reconstruct_element(element.sub_element(), cell=cell), element.restriction_domain()) if isinstance(element, (ufl.InteriorElement, ufl.HDivElement, ufl.HCurlElement, ufl.BrokenElement, ufl.FacetElement)): return type(element)(reconstruct_element(element._element, cell=cell)) if isinstance(element, ufl.TensorProductElement): return ufl.TensorProductElement(*element.sub_elements(), cell=cell) if isinstance(element, ufl.MixedElement): eles = [ reconstruct_element(e, cell=cell) for e in element.sub_elements() ] return ufl.MixedElement(*eles) raise NotImplementedError( "Don't know how to reconstruct element of type %s" % type(element))