def count_flops(n): mesh = Mesh(VectorElement('CG', interval, 1)) tfs = FunctionSpace(mesh, TensorElement('DG', interval, 1, shape=(n, n))) vfs = FunctionSpace(mesh, VectorElement('DG', interval, 1, dim=n)) ensemble_f = Coefficient(vfs) ensemble2_f = Coefficient(vfs) phi = TestFunction(tfs) i, j = indices(2) nc = 42 # magic number L = ((IndexSum( IndexSum( Product(nc * phi[i, j], Product(ensemble_f[i], ensemble_f[i])), MultiIndex((i, ))), MultiIndex((j, ))) * dx) + (IndexSum( IndexSum( Product(nc * phi[i, j], Product( ensemble2_f[j], ensemble2_f[j])), MultiIndex( (i, ))), MultiIndex((j, ))) * dx) - (IndexSum( IndexSum( 2 * nc * Product(phi[i, j], Product(ensemble_f[i], ensemble2_f[j])), MultiIndex((i, ))), MultiIndex((j, ))) * dx)) kernel, = compile_form(L, parameters=dict(mode='spectral')) return EstimateFlops().visit(kernel.ast)
def __init__(self, mesh, element, name='fspace'): self._themiselement = ThemisElement(element) self.ncomp = self._themiselement.get_ncomp() self._mesh = mesh self._name = name self._spaces = [ self, ] self.nspaces = 1 self.npatches = mesh.npatches UFLFunctionSpace.__init__(self, mesh, element) #create das and lgmaps self._composite_da = PETSc.DMComposite().create() self._da = [] self._lgmaps = [] self._component_offsets = [] for ci in xrange(self.ncomp): self._component_offsets.append(self.npatches * ci) das = [] lgmaps = [] for bi in range(self.npatches): das.append(mesh.create_dof_map(self._themiselement, ci, bi)) lgmaps.append(das[bi].getLGMap()) self._composite_da.addDM(das[bi]) self._da.append(das) self._lgmaps.append(lgmaps) self._composite_da.setUp() self._component_lgmaps = self._composite_da.getLGMaps() self._overall_lgmap = self._composite_da.getLGMap() self._cb_lis = self._composite_da.getLocalISs()
def set_cell_sizes(self, domain): """Setup a fake coefficient for "cell sizes". :arg domain: The domain of the integral. This is required for scaling of derivative basis functions on physically mapped elements (Argyris, Bell, etc...). We need a measure of the mesh size around each vertex (hence this lives in P1). Should the domain have topological dimension 0 this does nothing. """ if domain.ufl_cell().topological_dimension() > 0: # Can't create P1 since only P0 is a valid finite element if # topological_dimension is 0 and the concept of "cell size" # is not useful for a vertex. f = Coefficient( FunctionSpace(domain, FiniteElement("P", domain.ufl_cell(), 1))) funarg, expression = prepare_coefficient( f, "cell_sizes", self.scalar_type, interior_facet=self.interior_facet) self.cell_sizes_arg = funarg self._cell_sizes = expression
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)
def set_coefficients(self, integral_data, form_data): """Prepare the coefficients of the form. :arg integral_data: UFL integral data :arg form_data: UFL form data """ coefficients = [] coefficient_numbers = [] # enabled_coefficients is a boolean array that indicates which # of reduced_coefficients the integral requires. for i in range(len(integral_data.enabled_coefficients)): if integral_data.enabled_coefficients[i]: coefficient = form_data.reduced_coefficients[i] if type(coefficient.ufl_element()) == ufl_MixedElement: split = [ Coefficient( FunctionSpace(coefficient.ufl_domain(), element)) for element in coefficient.ufl_element().sub_elements() ] coefficients.extend(split) self.coefficient_split[coefficient] = split else: coefficients.append(coefficient) # This is which coefficient in the original form the # current coefficient is. # Consider f*v*dx + g*v*ds, the full form contains two # coefficients, but each integral only requires one. coefficient_numbers.append( form_data.original_coefficient_positions[i]) for i, coefficient in enumerate(coefficients): self.coefficient_args.append( self._coefficient(coefficient, "w_%d" % i)) self.kernel.coefficient_numbers = tuple(coefficient_numbers)
def set_coefficients(self, integral_data, form_data): """Prepare the coefficients of the form. :arg integral_data: UFL integral data :arg form_data: UFL form data """ name = "w" self.coefficient_args = [ coffee.Decl(SCALAR_TYPE, coffee.Symbol(name), pointers=[("const",), ()], qualifiers=["const"]) ] # enabled_coefficients is a boolean array that indicates which # of reduced_coefficients the integral requires. for n in range(len(integral_data.enabled_coefficients)): if not integral_data.enabled_coefficients[n]: continue coeff = form_data.reduced_coefficients[n] if type(coeff.ufl_element()) == ufl_MixedElement: coeffs = [Coefficient(FunctionSpace(coeff.ufl_domain(), element)) for element in coeff.ufl_element().sub_elements()] self.coefficient_split[coeff] = coeffs else: coeffs = [coeff] expressions = prepare_coefficients(coeffs, n, name, self.interior_facet) self.coefficient_map.update(zip(coeffs, expressions))
def mass_dg(cell, degree): m = Mesh(VectorElement('Q', cell, 1)) V = FunctionSpace(m, FiniteElement('DQ', cell, degree, variant='spectral')) u = TrialFunction(V) v = TestFunction(V) # In this case, the estimated quadrature degree will give the # correct number of quadrature points by luck. return u * v * dx
def test_mini(): m = Mesh(VectorElement('CG', triangle, 1)) P1 = FiniteElement('Lagrange', triangle, 1) B = FiniteElement("Bubble", triangle, 3) V = FunctionSpace(m, VectorElement(P1 + B)) u = TrialFunction(V) v = TestFunction(V) a = inner(grad(u), grad(v)) * dx count_flops(a)
def set_coordinates(self, domain): """Prepare the coordinate field. :arg domain: :class:`ufl.Domain` """ # Create a fake coordinate coefficient for a domain. f = Coefficient(FunctionSpace(domain, domain.ufl_coordinate_element())) self.domain_coordinate[domain] = f self.coordinates_arg = self._coefficient(f, "coords")
def elasticity(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, VectorElement('CG', cell, degree)) u = TrialFunction(V) v = TestFunction(V) def eps(u): return 0.5 * (grad(u) + grad(u).T) return inner(eps(u), eps(v)) * dx
def __init__(self, mesh, element, name='fspace', si=0, parent=None): self._themiselement = ThemisElement(element) self._uflelement = element self.interpolatory = self._themiselement.interpolatory self.ncomp = self._themiselement.ncomp self._mesh = mesh self._name = name self._spaces = [ self, ] self.nspaces = 1 self._si = si if parent is None: self._parent = self else: self._parent = parent UFLFunctionSpace.__init__(self, mesh, element) # create das and lgmaps self._composite_da = PETSc.DMComposite().create() self._da = [] self._lgmaps = [] self._component_offsets = [] for ci in range(self.ncomp): self._component_offsets.append(ci) da = mesh.create_dof_map(self._themiselement, ci) lgmap = da.getLGMap() self._composite_da.addDM(da) self._da.append(da) self._lgmaps.append(lgmap) self._composite_da.setUp() self._component_lgmaps = self._composite_da.getLGMaps() self._overall_lgmap = self._composite_da.getLGMap() self._cb_lis = self._composite_da.getLocalISs()
def set_cell_sizes(self, domain): """Setup a fake coefficient for "cell sizes". :arg domain: The domain of the integral. This is required for scaling of derivative basis functions on physically mapped elements (Argyris, Bell, etc...). We need a measure of the mesh size around each vertex (hence this lives in P1). """ f = Coefficient(FunctionSpace(domain, FiniteElement("P", domain.ufl_cell(), 1))) funarg, expression = prepare_coefficient(f, "cell_sizes", self.scalar_type, interior_facet=self.interior_facet) self.cell_sizes_arg = funarg self._cell_sizes = expression
def laplace(cell, degree): m = Mesh(VectorElement('Q', cell, 1)) V = FunctionSpace(m, FiniteElement('Q', cell, degree, variant='spectral')) u = TrialFunction(V) v = TestFunction(V) return dot(grad(u), grad(v))*dx(scheme=gll_quadrature_rule(cell, degree))
def mass_dg(cell, degree): m = Mesh(VectorElement('Q', cell, 1)) V = FunctionSpace(m, FiniteElement('DQ', cell, degree, variant='spectral')) u = TrialFunction(V) v = TestFunction(V) return u*v*dx(scheme=gl_quadrature_rule(cell, degree))
# UFL input for the Matrix-free Poisson Demo # ================================== from ufl import (Coefficient, Constant, FiniteElement, FunctionSpace, Mesh, TestFunction, TrialFunction, VectorElement, action, dx, grad, inner, triangle) coord_element = VectorElement("Lagrange", triangle, 1) mesh = Mesh(coord_element) # Function Space element = FiniteElement("Lagrange", triangle, 2) V = FunctionSpace(mesh, element) # Trial and test functions u = TrialFunction(V) v = TestFunction(V) # Define a constant RHS f = Constant(V) # Define the bilinear and linear forms according to the # variational formulation of the equations:: a = inner(grad(u), grad(v)) * dx L = inner(f, v) * dx # Define linear form representing the action of the form "a" on # the coefficient "ui" ui = Coefficient(V) M = action(a, ui) # Define form to compute the L2 norm of the error
def W(V, Q): mesh = V.ufl_domain() return FunctionSpace(mesh, MixedElement(V.ufl_element(), Q.ufl_element()))
def initialize_data(self): """ Extract required objects for defining error control forms. This will be stored, reused and in particular named. """ # Developer's note: The UFL-FFC-DOLFIN--PyDOLFIN toolchain for # error control is quite fine-tuned. In particular, the order # of coefficients in forms is (and almost must be) used for # their assignment. This means that the order in which these # coefficients are defined matters and should be considered # fixed. from ufl import FiniteElement, FunctionSpace, Coefficient from ufl.algorithms.elementtransformations import tear, increase_order # Primal trial element space self._V = self.u.ufl_function_space() # Extract domain domain = self.u.ufl_domain() # Primal test space == Dual trial space Vhat = self.weak_residual.arguments()[0].ufl_function_space() # Discontinuous version of primal trial element space self._dV = FunctionSpace(domain, tear(self._V.ufl_element())) # Extract geometric dimension gdim = domain.geometric_dimension() # Coefficient representing improved dual E = FunctionSpace(domain, increase_order(Vhat.ufl_element())) self._Ez_h = Coefficient(E) self.ec_names[id(self._Ez_h)] = "__improved_dual" # Coefficient representing cell bubble function Belm = FiniteElement("B", domain.ufl_cell(), gdim + 1) Bfs = FunctionSpace(domain, Belm) self._b_T = Coefficient(Bfs) self.ec_names[id(self._b_T)] = "__cell_bubble" # Coefficient representing strong cell residual self._R_T = Coefficient(self._dV) self.ec_names[id(self._R_T)] = "__cell_residual" # Coefficient representing cell cone function Celm = FiniteElement("DG", domain.ufl_cell(), gdim) Cfs = FunctionSpace(domain, Celm) self._b_e = Coefficient(Cfs) self.ec_names[id(self._b_e)] = "__cell_cone" # Coefficient representing strong facet residual self._R_dT = Coefficient(self._dV) self.ec_names[id(self._R_dT)] = "__facet_residual" # Define discrete dual on primal test space self._z_h = Coefficient(Vhat) self.ec_names[id(self._z_h)] = "__discrete_dual_solution" # Piecewise constants for assembling indicators self._DG0 = FunctionSpace(domain, FiniteElement("DG", domain.ufl_cell(), 0))
def mass(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, FiniteElement('CG', cell, degree)) u = TrialFunction(V) v = TestFunction(V) return u * v * dx
def form(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, VectorElement('CG', cell, degree)) f = Coefficient(V) return div(f) * dx
def Q(mesh): return FunctionSpace(mesh, FiniteElement("RT", triangle, 1))
def poisson(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, FiniteElement('CG', cell, degree)) u = TrialFunction(V) v = TestFunction(V) return dot(grad(u), grad(v)) * dx
def helmholtz(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, FiniteElement('CG', cell, degree)) u = TrialFunction(V) v = TestFunction(V) return (u * v + dot(grad(u), grad(v))) * dx
def form(cell, degree): m = Mesh(VectorElement('CG', cell, 1)) V = FunctionSpace(m, FiniteElement('CG', cell, degree)) v = TestFunction(V) return v * dx
def V(mesh): return FunctionSpace(mesh, VectorElement("DP", triangle, 1))