def hyperelasticity(domain, q, p, nf=0): # Based on https://github.com/firedrakeproject/firedrake-bench/blob/experiments/forms/firedrake_forms.py V = ufl.FunctionSpace(domain, ufl.VectorElement('P', domain.ufl_cell(), q)) P = ufl.FunctionSpace(domain, ufl.VectorElement('P', domain.ufl_cell(), p)) v = ufl.TestFunction(V) du = ufl.TrialFunction(V) # Incremental displacement u = ufl.Coefficient(V) # Displacement from previous iteration B = ufl.Coefficient(V) # Body force per unit mass # Kinematics I = ufl.Identity(domain.ufl_cell().topological_dimension()) F = I + ufl.grad(u) # Deformation gradient C = F.T*F # Right Cauchy-Green tensor E = (C - I)/2 # Euler-Lagrange strain tensor E = ufl.variable(E) # Material constants mu = ufl.Constant(domain) # Lame's constants lmbda = ufl.Constant(domain) # Strain energy function (material model) psi = lmbda/2*(ufl.tr(E)**2) + mu*ufl.tr(E*E) S = ufl.diff(psi, E) # Second Piola-Kirchhoff stress tensor PK = F*S # First Piola-Kirchoff stress tensor # Variational problem it = ufl.inner(PK, ufl.grad(v)) - ufl.inner(B, v) f = [ufl.Coefficient(P) for _ in range(nf)] return ufl.derivative(reduce(ufl.inner, list(map(ufl.div, f)) + [it])*ufl.dx, u, du)
def Parameter(domain, parameter, dimRange=None, count=None): if dimRange is None: constant = ufl.Constant(domain, count) else: constant = ufl.VectorConstant(domain, dim=dimRange, count=count) constant.parameter = parameter return constant
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)
def test_laplace_bilinear_form_2d(mode, expected_result, compile_args): cell = ufl.triangle element = ufl.FiniteElement("Lagrange", cell, 1) kappa = ufl.Constant(cell, shape=(2, 2)) u, v = ufl.TrialFunction(element), ufl.TestFunction(element) a = ufl.tr(kappa) * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx forms = [a] compiled_forms, module = ffcx.codegeneration.jit.compile_forms( forms, parameters={'scalar_type': mode}, cffi_extra_compile_args=compile_args) for f, compiled_f in zip(forms, compiled_forms): assert compiled_f.rank == len(f.arguments()) ffi = cffi.FFI() form0 = compiled_forms[0][0] assert form0.num_cell_integrals == 1 ids = np.zeros(form0.num_cell_integrals, dtype=np.int32) form0.get_cell_integral_ids(ffi.cast('int *', ids.ctypes.data)) assert ids[0] == -1 default_integral = form0.create_cell_integral(ids[0]) c_type, np_type = float_to_type(mode) A = np.zeros((3, 3), dtype=np_type) w = np.array([], dtype=np_type) kappa_value = np.array([[1.0, 2.0], [3.0, 4.0]]) c = np.array(kappa_value.flatten(), dtype=np_type) coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64) default_integral.tabulate_tensor( 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), ffi.NULL, ffi.NULL, 0) assert np.allclose(A, np.trace(kappa_value) * expected_result)
def NamedConstant(value, name=None, dimRange=None, count=None): if not isinstance(value, tuple) and not isinstance( value, list) and not isNumber(value): try: domainCell = value.cell() except AttributeError: domainCell = cell(value) if dimRange is None: value = 0 else: value = (0, ) * dimRange else: domainCell = None return Constant(value, cell=domainCell, name=name) if dimRange is None: constant = ufl.Constant(domainCell, count) constant.values = 0 else: constant = ufl.VectorConstant(domainCell, dim=dimRange, count=count) constant.values = (0, ) * dimRange constant.name = name return constant