def test_additivity(mode): mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = dolfinx.FunctionSpace(mesh, ("CG", 1)) f1 = dolfinx.Function(V) f2 = dolfinx.Function(V) f3 = dolfinx.Function(V) with f1.vector.localForm() as f1_local: f1_local.set(1.0) with f2.vector.localForm() as f2_local: f2_local.set(2.0) with f3.vector.localForm() as f3_local: f3_local.set(3.0) j1 = ufl.inner(f1, f1) * ufl.dx(mesh) j2 = ufl.inner(f2, f2) * ufl.ds(mesh) j3 = ufl.inner(ufl.avg(f3), ufl.avg(f3)) * ufl.dS(mesh) # Assemble each scalar form separately J1 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1), op=MPI.SUM) J2 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j2), op=MPI.SUM) J3 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j3), op=MPI.SUM) # Sum forms and assemble the result J12 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j2), op=MPI.SUM) J13 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j3), op=MPI.SUM) J23 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j2 + j3), op=MPI.SUM) J123 = mesh.mpi_comm().allreduce(dolfinx.fem.assemble_scalar(j1 + j2 + j3), op=MPI.SUM) # Compare assembled values assert (J1 + J2) == pytest.approx(J12) assert (J1 + J3) == pytest.approx(J13) assert (J2 + J3) == pytest.approx(J23) assert (J1 + J2 + J3) == pytest.approx(J123)
def test_basic_interior_facet_assembly(): ghost_mode = dolfin.cpp.mesh.GhostMode.none if (dolfin.MPI.size(dolfin.MPI.comm_world) > 1): ghost_mode = dolfin.cpp.mesh.GhostMode.shared_facet mesh = dolfin.RectangleMesh( dolfin.MPI.comm_world, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1.0, 1.0, 0.0])], [5, 5], cell_type=dolfin.cpp.mesh.CellType.Type.triangle, ghost_mode=ghost_mode) V = dolfin.function.FunctionSpace(mesh, ("DG", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS A = dolfin.fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) L = ufl.conj(ufl.avg(v)) * ufl.dS b = dolfin.fem.assemble_vector(L) b.assemble() assert isinstance(b, PETSc.Vec)
def test_additivity(mode): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) f1 = Function(V) f2 = Function(V) f3 = Function(V) f1.x.array[:] = 1.0 f2.x.array[:] = 2.0 f3.x.array[:] = 3.0 j1 = ufl.inner(f1, f1) * ufl.dx(mesh) j2 = ufl.inner(f2, f2) * ufl.ds(mesh) j3 = ufl.inner(ufl.avg(f3), ufl.avg(f3)) * ufl.dS(mesh) # Assemble each scalar form separately J1 = mesh.comm.allreduce(assemble_scalar(form(j1)), op=MPI.SUM) J2 = mesh.comm.allreduce(assemble_scalar(form(j2)), op=MPI.SUM) J3 = mesh.comm.allreduce(assemble_scalar(form(j3)), op=MPI.SUM) # Sum forms and assemble the result J12 = mesh.comm.allreduce(assemble_scalar(form(j1 + j2)), op=MPI.SUM) J13 = mesh.comm.allreduce(assemble_scalar(form(j1 + j3)), op=MPI.SUM) J23 = mesh.comm.allreduce(assemble_scalar(form(j2 + j3)), op=MPI.SUM) J123 = mesh.comm.allreduce(assemble_scalar(form(j1 + j2 + j3)), op=MPI.SUM) # Compare assembled values assert (J1 + J2) == pytest.approx(J12) assert (J1 + J3) == pytest.approx(J13) assert (J2 + J3) == pytest.approx(J23) assert (J1 + J2 + J3) == pytest.approx(J123)
def test_basic_interior_facet_assembly(): mesh = create_rectangle(MPI.COMM_WORLD, [np.array([0.0, 0.0]), np.array([1.0, 1.0])], [5, 5], cell_type=CellType.triangle, ghost_mode=GhostMode.shared_facet) V = FunctionSpace(mesh, ("DG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS a = form(a) A = assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) L = ufl.conj(ufl.avg(v)) * ufl.dS L = form(L) b = assemble_vector(L) b.assemble() assert isinstance(b, PETSc.Vec)
def test_ghost_mesh_dS_assembly(mode, dS): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) dS = dS(mesh) a = form(inner(avg(u), avg(v)) * dS) # Initial assembly A = fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) # Check that the norms are the same for all three modes normA = A.norm() print(normA) assert normA == pytest.approx(2.1834054713561906, rel=1.e-6, abs=1.e-12)
def test_coefficents_non_constant(): "Test packing coefficients with non-constant values" mesh = create_unit_square(MPI.COMM_WORLD, 3, 5) V = FunctionSpace( mesh, ("Lagrange", 3)) # degree 3 so that interpolation is exact u = Function(V) u.interpolate(lambda x: x[0] * x[1]**2) x = SpatialCoordinate(mesh) v = ufl.TestFunction(V) # -- Volume integral vector F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * dx) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0) # -- Exterior facet integral vector F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * ds) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0) # -- Interior facet integral vector V = FunctionSpace(mesh, ("DG", 3)) # degree 3 so that interpolation is exact u0 = Function(V) u0.interpolate(lambda x: x[1]**2) u1 = Function(V) u1.interpolate(lambda x: x[0]) x = SpatialCoordinate(mesh) v = ufl.TestFunction(V) F = (ufl.inner(u1('+') * u0('-'), ufl.avg(v)) - ufl.inner(x[0] * x[1]**2, ufl.avg(v))) * ufl.dS F = form(F) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0)
def test_basic_interior_facet_assembly(): mesh = dolfinx.RectangleMesh( MPI.COMM_WORLD, [numpy.array([0.0, 0.0, 0.0]), numpy.array([1.0, 1.0, 0.0])], [5, 5], cell_type=dolfinx.cpp.mesh.CellType.triangle, ghost_mode=dolfinx.cpp.mesh.GhostMode.shared_facet) V = fem.FunctionSpace(mesh, ("DG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS A = dolfinx.fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) L = ufl.conj(ufl.avg(v)) * ufl.dS b = dolfinx.fem.assemble_vector(L) b.assemble() assert isinstance(b, PETSc.Vec)
def error_indicators(self): """ Generate and return linear form defining error indicators """ # Extract these to increase readability R_T = self._R_T R_dT = self._R_dT z = self._Ez_h z_h = self._z_h # Define linear form for computing error indicators v = self.module.TestFunction(self._DG0) eta_T = (v * inner(R_T, z - z_h) * dx(self.domain) + avg(v)*(inner(R_dT('+'), (z - z_h)('+')) + inner(R_dT('-'), (z - z_h)('-'))) * dS(self.domain) + v * inner(R_dT, z - z_h) * ds(self.domain)) return eta_T
def qoi_varf(u,m): return ufl.avg(ufl.exp(m)*ufl.dot( ufl.grad(u), n) )*dss(1)
# array of displacement values to apply at right boundary stretchVals = np.hstack(( ldot * timeVals[:len(timeVals) // 2], ldot * (-timeVals[len(timeVals) // 2:] + 2 * timeVals[len(timeVals) // 2]), )) svals = np.zeros_like(stretchVals) plt.plot(timeVals, stretchVals) plt.savefig("stretchesVisco.png") plt.close() # stabilization parameters h = FacetArea(mesh) h_avg = avg(h) # new variable name to take derivatives FF = Identity(3) + grad(u) CC = FF.T * FF Fv = variable(FF) S = diff(freeEnergy(Fv.T * Fv, CCv), Fv) # first PK stress dl_interp(CC, C) dl_interp(CC, Cn) my_identity = grad(SpatialCoordinate(mesh)) dl_interp(my_identity, CCv) dl_interp(my_identity, Cvn) dl_interp(my_identity, C_quart) dl_interp(my_identity, C_thr_quart)
# <markdowncell> # Error estimator # <codecell> fvspace = dune.fem.space.finiteVolume(uh.space.grid) estimate = fvspace.interpolate([0], name="estimate") chi = ufl.TestFunction(fvspace) hT = ufl.MaxCellEdgeLength(fvspace.cell()) he = ufl.MaxFacetEdgeLength(fvspace.cell())('+') n = ufl.FacetNormal(fvspace.cell()) residual = (u - uh_n) / dt - div(diffusiveFlux) + source(u, u, u, vh) estimator_ufl = hT**2 * residual**2 * chi * dx +\ he * inner( jump(diffusiveFlux), n('+'))**2 * avg(chi) * dS estimator = dune.fem.operator.galerkin(estimator_ufl) # <markdowncell> # Time loop # <codecell> nextSaveTime = saveInterval count = 0 levelFunction = dune.fem.function.levelFunction(gridView) gridView.writeVTK("spiral", pointdata=[uh, vh], number=count, celldata=[estimate, levelFunction]) count += 1
# The bilinear form a(v, u) and linear form L(v) for # Poisson's equation in a discontinuous Galerkin (DG) # formulation. from ufl import (Coefficient, Constant, FacetNormal, FiniteElement, TestFunction, TrialFunction, avg, dot, dS, ds, dx, grad, inner, jump, triangle) element = FiniteElement("Discontinuous Lagrange", triangle, 1) v = TestFunction(element) u = TrialFunction(element) f = Coefficient(element) n = FacetNormal(triangle) h = Constant(triangle) gN = Coefficient(element) alpha = 4.0 gamma = 8.0 a = inner(grad(v), grad(u)) * dx \ - inner(avg(grad(v)), jump(u, n)) * dS \ - inner(jump(v, n), avg(grad(u))) * dS \ + alpha / h('+') * dot(jump(v, n), jump(u, n)) * dS \ - inner(grad(v), u * n) * ds \ - inner(v * n, grad(u)) * ds \ + gamma / h * v * u * ds L = v * f * dx + v * gN * ds
def test_manufactured_poisson_dg(degree, filename, datadir): """ Manufactured Poisson problem, solving u = x[component]**n, where n is the degree of the Lagrange function space. """ with XDMFFile(MPI.COMM_WORLD, os.path.join(datadir, filename), "r", encoding=XDMFFile.Encoding.ASCII) as xdmf: mesh = xdmf.read_mesh(name="Grid") V = FunctionSpace(mesh, ("DG", degree)) u, v = TrialFunction(V), TestFunction(V) # Exact solution x = SpatialCoordinate(mesh) u_exact = x[1]**degree # Coefficient k = Function(V) k.vector.set(2.0) k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # Source term f = -div(k * grad(u_exact)) # Mesh normals and element size n = FacetNormal(mesh) h = CellDiameter(mesh) h_avg = (h("+") + h("-")) / 2.0 # Penalty parameter alpha = 32 dx_ = dx(metadata={"quadrature_degree": -1}) ds_ = ds(metadata={"quadrature_degree": -1}) dS_ = dS(metadata={"quadrature_degree": -1}) a = inner(k * grad(u), grad(v)) * dx_ \ - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \ - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \ + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \ - inner(k * grad(u), v * n) * ds_ \ - inner(u * n, k * grad(v)) * ds_ \ + (alpha / h) * inner(k * u, v) * ds_ L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \ + (alpha / h) * inner(k * u_exact, v) * ds_ for integral in a.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( a) for integral in L.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( L) b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) A = assemble_matrix(a, []) A.assemble() # Create LU linear solver solver = PETSc.KSP().create(MPI.COMM_WORLD) solver.setType(PETSc.KSP.Type.PREONLY) solver.getPC().setType(PETSc.PC.Type.LU) solver.setOperators(A) # Solve uh = Function(V) solver.solve(b, uh.vector) uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) error = mesh.mpi_comm().allreduce(assemble_scalar((u_exact - uh)**2 * dx), op=MPI.SUM) assert np.absolute(error) < 1.0e-14
def compute(space, epsilon, weakBnd, skeleton, mol=None): u = TrialFunction(space) v = TestFunction(space) n = FacetNormal(space) he = avg(CellVolume(space)) / FacetArea(space) hbnd = CellVolume(space) / FacetArea(space) x = SpatialCoordinate(space) exact = uflFunction(space.gridView, name="exact", order=3, ufl=sin(x[0] * x[1])) uh = space.interpolate(exact, name="solution") # diffusion factor eps = Constant(epsilon, "eps") # transport direction and upwind flux b = as_vector([1, 0]) hatb = (dot(b, n) + abs(dot(b, n))) / 2.0 # characteristic function for left/right boundary dD = conditional((1 + x[0]) * (1 - x[0]) < 1e-10, 1, 0) # penalty parameter beta = Constant(20 * space.order**2, "beta") rhs = -(div(eps * grad(exact) - b * exact)) * v * dx aInternal = dot(eps * grad(u) - b * u, grad(v)) * dx aInternal -= eps * dot(grad(exact), n) * v * (1 - dD) * ds diffSkeleton = eps*beta/he*jump(u)*jump(v)*dS -\ eps*dot(avg(grad(u)),n('+'))*jump(v)*dS -\ eps*jump(u)*dot(avg(grad(v)),n('+'))*dS if weakBnd: diffSkeleton += eps*beta/hbnd*(u-exact)*v*dD*ds -\ eps*dot(grad(exact),n)*v*dD*ds advSkeleton = jump(hatb * u) * jump(v) * dS if weakBnd: advSkeleton += (hatb * u + (dot(b, n) - hatb) * exact) * v * dD * ds if skeleton: form = aInternal + diffSkeleton + advSkeleton else: form = aInternal if weakBnd and skeleton: strongBC = None else: strongBC = DirichletBC(space, exact, dD) if space.storage[0] == "numpy": solver = { "solver": ("suitesparse", "umfpack"), "parameters": { "newton.verbose": True, "newton.linear.verbose": False, "newton.linear.tolerance": 1e-5, } } else: solver = { "solver": "bicgstab", "parameters": { "newton.linear.preconditioning.method": "ilu", "newton.linear.tolerance": 1e-13, "newton.verbose": True, "newton.linear.verbose": False } } if mol == 'mol': scheme = molSolutionScheme([form == rhs, strongBC], **solver) else: scheme = solutionScheme([form == rhs, strongBC], **solver) eoc = [] info = scheme.solve(target=uh) error = dot(uh - exact, uh - exact) error0 = math.sqrt(integrate(gridView, error, order=5)) print(error0, " # output", flush=True) for i in range(3): gridView.hierarchicalGrid.globalRefine(1) uh.interpolate(exact) scheme.solve(target=uh) error = dot(uh - exact, uh - exact) error1 = math.sqrt(integrate(gridView, error, order=5)) eoc += [math.log(error1 / error0) / math.log(0.5)] print(i, error0, error1, eoc, " # output", flush=True) error0 = error1 # print(space.order,epsilon,eoc) if (eoc[-1] - (space.order + 1)) < -0.1: print("ERROR:", space.order, epsilon, eoc) return eoc
def run_dg_test(mesh, V, degree): """ Manufactured Poisson problem, solving u = x[component]**n, where n is the degree of the Lagrange function space. """ u, v = TrialFunction(V), TestFunction(V) # Exact solution x = SpatialCoordinate(mesh) u_exact = x[1]**degree # Coefficient k = Function(V) k.vector.set(2.0) k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) # Source term f = -div(k * grad(u_exact)) # Mesh normals and element size n = FacetNormal(mesh) h = CellDiameter(mesh) h_avg = (h("+") + h("-")) / 2.0 # Penalty parameter alpha = 32 dx_ = dx(metadata={"quadrature_degree": -1}) ds_ = ds(metadata={"quadrature_degree": -1}) dS_ = dS(metadata={"quadrature_degree": -1}) with common.Timer("Compile forms"): a = inner(k * grad(u), grad(v)) * dx_ \ - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \ - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \ + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \ - inner(k * grad(u), v * n) * ds_ \ - inner(u * n, k * grad(v)) * ds_ \ + (alpha / h) * inner(k * u, v) * ds_ L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \ + (alpha / h) * inner(k * u_exact, v) * ds_ for integral in a.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( a) for integral in L.integrals(): integral.metadata( )["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree( L) with common.Timer("Assemble vector"): b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) with common.Timer("Assemble matrix"): A = assemble_matrix(a, []) A.assemble() with common.Timer("Solve"): # Create LU linear solver solver = PETSc.KSP().create(MPI.COMM_WORLD) solver.setType(PETSc.KSP.Type.PREONLY) solver.getPC().setType(PETSc.PC.Type.LU) solver.setOperators(A) # Solve uh = Function(V) solver.solve(b, uh.vector) uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) with common.Timer("Error functional compile"): # Calculate error M = (u_exact - uh)**2 * dx M = fem.Form(M) with common.Timer("Error assembly"): error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM) common.list_timings(MPI.COMM_WORLD, [common.TimingType.wall]) assert np.absolute(error) < 1.0e-14
def model(space, epsilon, weakBnd, skeleton, useMol): u = TrialFunction(space) v = TestFunction(space) n = FacetNormal(space) he = avg(CellVolume(space)) / FacetArea(space) hbnd = CellVolume(space) / FacetArea(space) x = SpatialCoordinate(space) #exact = sin(x[0]*x[1]) # atan(1*x[1]) exact = uflFunction(space.gridView, name="exact", order=3, ufl=sin(x[0] * x[1])) # diffusion factor eps = 1 # Constant(epsilon,"eps") # transport direction and upwind flux b = as_vector([1, 0]) hatb = (dot(b, n) + abs(dot(b, n))) / 2.0 # characteristic function for left/right boundary dD = conditional((1 + x[0]) * (1 - x[0]) < 1e-10, 1, 0) # penalty parameter beta = Constant(10 * space.order**2 if space.order > 0 else 1, "beta") rhs = (-div(eps * grad(exact) - b * exact) + exact) * v * dx aInternal = (dot(eps * grad(u) - b * u, grad(v)) + dot(u, v)) * dx diffSkeleton = eps*beta/he*jump(u)*jump(v)*dS -\ eps*dot(avg(grad(u)),n('+'))*jump(v)*dS -\ eps*jump(u)*dot(avg(grad(v)),n('+'))*dS diffSkeleton -= eps * dot(grad(exact), n) * v * (1 - dD) * ds if weakBnd: diffSkeleton += eps*beta/hbnd*(u-exact)*v*dD*ds -\ eps*dot(grad(exact),n)*v*dD*ds advSkeleton = jump(hatb * u) * jump(v) * dS if weakBnd: advSkeleton += (hatb * u + (dot(b, n) - hatb) * exact) * v * dD * ds if skeleton: form = aInternal + diffSkeleton + advSkeleton else: form = aInternal if weakBnd and skeleton: strongBC = None else: strongBC = None # DirichletBC(space,exact,dD) if space.storage[0] == "fem": solver = {"solver": ("suitesparse", "umfpack")} else: solver = { "solver": "bicgstab", "parameters": { "newton.linear.preconditioning.method": "jacobi", "newton.linear.tolerance": 1e-13 } } if useMol: scheme = solutionMolScheme([form == rhs, strongBC], **solver) else: scheme = solutionScheme([form == rhs, strongBC], **solver) uh = space.interpolate(exact, name="solution") A = linear(scheme) return scheme, uh, A, exact
# with Dirichlet boundary conditions. Here $\varepsilon$ is a small # constant and $b$ a given vector. # <codecell> gridView = leafGridView([-1, -1], [1, 1], [20, 20]) order = 2 from dune.fem.space import dglegendre as dgSpace space = dgSpace(gridView, order=order) from ufl import avg, jump, dS, ds,\ CellVolume, FacetArea, FacetNormal,\ as_vector, atan u = TrialFunction(space) v = TestFunction(space) n = FacetNormal(space) he = avg( CellVolume(space) ) / FacetArea(space) hbnd = CellVolume(space) / FacetArea(space) x = SpatialCoordinate(space) # diffusion factor eps = Constant(0.1,"eps") # transport direction and upwind flux b = as_vector([1,0]) hatb = (dot(b, n) + abs(dot(b, n)))/2.0 # boundary values (for left/right boundary) dD = conditional((1+x[0])*(1-x[0])<1e-10,1,0) g = conditional(x[0]<0,atan(10*x[1]),0) # penalty parameter beta = 10*order*order aInternal = dot(eps*grad(u) - b*u, grad(v)) * dx
# Copyright (C) 2009 Kristian B. Oelgaard # # This file is part of UFL. # # UFL is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # UFL is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with UFL. If not, see <http://www.gnu.org/licenses/>. # # Restriction of a finite element. # The below syntax show how one can restrict a higher order Lagrange element # to only take into account those DOFs that live on the facets. from ufl import (FiniteElement, TestFunction, TrialFunction, avg, dS, ds, triangle) # Restricted element CG_R = FiniteElement("Lagrange", triangle, 4)["facet"] u_r = TrialFunction(CG_R) v_r = TestFunction(CG_R) a = avg(v_r) * avg(u_r) * dS + v_r * u_r * ds
top = 1.0 if dim == 3: top = ufl.conditional(x[2] > 1.25, 1, 0) initial_u = iu(x[1]) * top + iu(2.5 - x[1]) * (1.0 - top) initial_v = ufl.conditional(x[0] < 1.25, 0.5, 0) uh = space.interpolate(initial_u, name="u") uh_n = uh.copy() vh = space.interpolate(initial_v, name="v") vh_n = vh.copy() u = ufl.TrialFunction(space) phi = ufl.TestFunction(space) hT = ufl.MaxCellEdgeLength(space.cell()) hS = ufl.avg(ufl.MaxFacetEdgeLength(space.cell())) hs = ufl.MaxFacetEdgeLength(space.cell())('+') n = ufl.FacetNormal(space.cell()) ustar = lambda v: (v + spiral_b) / spiral_a diffusiveFlux = lambda w, d: spiral_D * d source = lambda u1, u2, u3, v: -1 / spiral_eps * u1 * (1 - u2) * (u3 - ustar(v) ) source = lambda u1, u2, u3, v: -1 / spiral_eps * u1 * (1 - u2) * (u3 - ustar(v) ) xForm = inner(diffusiveFlux(u, grad(u)), grad(phi)) * dx xForm += ufl.conditional(uh_n < ustar(vh_n), source(u, uh_n, uh_n, vh_n), source(uh_n, u, uh_n, vh_n)) * phi * dx # <markdowncell>
uh_pm1 = spcpm.interpolate( initial_u, name="u_p-1" ) uh_n = uh.copy() vh = space.interpolate( initial_v, name="v" ) vh_n = vh.copy() # <markdowncell> # Setting up the model # <codecell> u = ufl.TrialFunction(space) phi = ufl.TestFunction(space) n = ufl.FacetNormal(space) penalty = 5 * (maxOrder * ( maxOrder + 1 )) * spiral_D hT = ufl.MaxCellEdgeLength(space) hS = ufl.avg( ufl.MaxFacetEdgeLength(space) ) hs = ufl.MaxFacetEdgeLength(space)('+') ustar = lambda v: (v+spiral_b)/spiral_a diffusiveFlux = lambda w,d: spiral_D * d source = lambda u1,u2,u3,v: -1/spiral_eps * u1*(1-u2)*(u3-ustar(v)) xForm = inner(diffusiveFlux(u,grad(u)), grad(phi)) * dx xForm += ufl.conditional(uh_n<ustar(vh_n), source(u,uh_n,uh_n,vh_n), source(uh_n,u,uh_n,vh_n)) * phi * dx # dg terms # xForm -= ( inner( outer(jump(u), n('+')), avg(diffusiveFlux(u,grad(phi)))) +\ # inner( avg(diffusiveFlux(u,grad(u))), outer(jump(phi), n('+'))) ) * dS # xForm += penalty/hS * inner(jump(u), jump(phi)) * dS
# Test and trial functions vq = BlockTestFunction(W) (v, q) = block_split(vq) up = BlockTrialFunction(W) (u, p) = block_split(up) w = BlockFunction(W) w0 = BlockFunction(W) (u0, p0) = block_split(w0) n = FacetNormal(mesh) vc = CellVolume(mesh) fc = FacetArea(mesh) h = vc / fc h_avg = (vc("+") + vc("-")) / (2 * avg(fc)) penalty1 = 1.0 penalty2 = 10.0 theta = 1.0 # Constitutive parameters K = 1000.e3 nu = 0.25 E = K_nu_to_E(K, nu) # Pa 14 (mu_l, lmbda_l) = E_nu_to_mu_lmbda(E, nu) f_stress_y = Constant(-1.e3) f = Constant((0.0, 0.0)) # sink/source for displacement