def setup(): vertices = numpy.zeros((8, 2)) vertices[0] = [0, 0] for i in range(0, 7): vertices[i + 1] = [ math.cos(cornerAngle / 6 * math.pi / 180 * i), math.sin(cornerAngle / 6 * math.pi / 180 * i) ] triangles = numpy.array([[2, 1, 0], [0, 3, 2], [4, 3, 0], [0, 5, 4], [6, 5, 0], [0, 7, 6]]) domain = {"vertices": vertices, "simplices": triangles} gridView = adaptiveGridView(leafGridView(domain)) gridView.hierarchicalGrid.globalRefine(2) space = solutionSpace(gridView, order=order) from dune.fem.scheme import galerkin as solutionScheme u = TrialFunction(space) v = TestFunction(space) x = SpatialCoordinate(space.cell()) # exact solution for this angle Phi = cornerAngle / 180 * pi phi = atan_2(x[1], x[0]) + conditional(x[1] < 0, 2 * pi, 0) exact = dot(x, x)**(pi / 2 / Phi) * sin(pi / Phi * phi) a = dot(grad(u), grad(v)) * dx # set up the scheme laplace = solutionScheme( [a == 0, DirichletBC(space, exact, 1)], solver="cg", parameters={"newton.linear.preconditioning.method": "jacobi"}) uh = space.interpolate(0, name="solution") return uh, exact, laplace
def test(operator): model = [ equation, DirichletBC(uflSpace, [None, x[0]**2], 2), # bottom DirichletBC(uflSpace, [exact[0], None], 3), # top DirichletBC(uflSpace, [None, None], 4), # left DirichletBC(uflSpace, exact, 1) ] # right parameters = {"newton." + k: v for k, v in newtonParameter.items()} scheme = create.scheme(operator, model, spc, parameters=parameters) solution = spc.interpolate([0, 0], name="solution") scheme.solve(target=solution) l2errA = sqrt(integrate(grid, (solution - exact)**2, 5)) grid.hierarchicalGrid.globalRefine(2) # note: without the `clear` the code can fail since the new dofs in 'solution' can be nan solution.clear() scheme.solve(target=solution) l2errB = sqrt(integrate(grid, (solution - exact)**2, 5)) return solution, l2errA, l2errB
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
exact_u = as_vector([x[1] * (1. - x[1]), 0]) exact_p = as_vector([(-2 * x[0] + 2) * mu]) f = as_vector([ 0, ] * grid.dimension) f += nu * exact_u mainModel = (nu * dot(u, v) + mu * inner(grad(u) + grad(u).T, grad(v)) - dot(f, v)) * dx gradModel = -inner(p[0] * Identity(grid.dimension), grad(v)) * dx divModel = -div(u) * q[0] * dx massModel = inner(p, q) * dx preconModel = inner(grad(p), grad(q)) * dx # can also use 'operator' everywhere mainOp = create.scheme("galerkin", (mainModel == 0, DirichletBC(spcU, exact_u, 1)), spcU) gradOp = create.operator("galerkin", gradModel, spcP, spcU) divOp = create.operator("galerkin", divModel, spcU, spcP) massOp = create.scheme("galerkin", massModel == 0, spcP) preconOp = create.scheme("galerkin", preconModel == 0, spcP) mainOp.model.mu = 0.1 mainOp.model.nu = 0.01 velocity = spcU.interpolate([ 0, ] * spcU.dimRange, name="velocity") pressure = spcP.interpolate([0], name="pressure") rhsVelo = velocity.copy() rhsPress = pressure.copy()
# to the dual problem with right hand side $J(\varphi_i)$ for all basis # functions $\varphi_i$. This is not directly expressible in UFL and we # therefore implement this using a small C++ function which we then export # to Python: # # .. literalinclude:: laplace-dwr.hh # # <codecell> from dune.fem.scheme import galerkin as solutionScheme spaceZ = solutionSpace(uh.space.grid, order=order + 1) u = TrialFunction(spaceZ) v = TestFunction(spaceZ) x = SpatialCoordinate(spaceZ) a = dot(grad(u), grad(v)) * dx dual = solutionScheme([a == 0, DirichletBC(spaceZ, 0)], solver="cg") z = spaceZ.interpolate(0, name="dual") zh = uh.copy(name="dual_h") point = common.FieldVector([0.4, 0.4]) pointFunctional = z.copy("dual_rhs") eh = expression2GF(uh.space.grid, abs(exact - uh), order=order + 1) computeFunctional = algorithm.load("pointFunctional", "laplace-dwr.hh", point, pointFunctional, eh) # <markdowncell> # <codecell> from dune.fem.space import finiteVolume as estimatorSpace from dune.fem.operator import galerkin as estimatorOp fvspace = estimatorSpace(uh.space.grid)
# \end{align*} # <codecell> from ufl import TestFunction, TrialFunction from dune.ufl import DirichletBC u = TrialFunction(space) v = TestFunction(space) from ufl import dx, grad, div, grad, dot, inner, sqrt, conditional, FacetNormal, ds a = dot(grad(u), grad(v)) * dx f = -div( grad(exact) ) g_N = grad(exact) n = FacetNormal(space) b = f*v*dx + dot(g_N,n)*conditional(x[0]>=1e-8,1,0)*v*ds dbc = DirichletBC(space,exact,x[0]<=1e-8) # <markdowncell> # With the model described as a ufl form, we can construct a scheme class # that provides the solve method which we can use to compute the solution: # <codecell> from dune.fem import parameter parameter.append({"fem.verboserank": -1}) from dune.fem.scheme import galerkin as solutionScheme scheme = solutionScheme([a == b, dbc], solver='cg') scheme.solve(target = u_h) # <markdowncell> # We can compute the error between the exact and the discrete solution by # using the `integrate` function described above:
saveInterval = 0.1 # define storage for discrete solutions uh = space.interpolate(x, name="uh") uh_old = uh.copy() # problem definition # space form xForm = inner(grad(u), grad(phi)) * dx # add time discretization form = dot(u - uh_old, phi) * dx + dt * xForm # define dirichlet boundary conditions - freezing the boundary bc = DirichletBC(space,x) # setup scheme dune.fem.parameter.append({"fem.verboserank": 0}) solverParameters =\ {"newton.tolerance": 1e-9, "newton.linear.tolerance": 1e-11, "newton.linear.preconditioning.method": "jacobi"} scheme = solutionScheme([form == 0, bc], space, solver="cg", parameters=solverParameters) nextSaveTime = saveInterval count = 0 # <markdowncell> # So far we can only plot x/y coordinates using matplotlib which does not
nu = Constant(0.01, "nu") u = TrialFunction(spcU) v = TestFunction(spcU) p = TrialFunction(spcP) q = TestFunction(spcP) exact_u = as_vector( [x[1] * (1.-x[1]), 0] ) exact_p = as_vector( [ (-2*x[0] + 2)*mu ] ) f = as_vector( [0,]*grid.dimension ) f += nu*exact_u mainModel = (nu*dot(u,v) + mu*inner(grad(u)+grad(u).T, grad(v)) - dot(f,v)) * dx gradModel = -inner( p[0]*Identity(grid.dimension), grad(v) ) * dx divModel = -div(u)*q[0] * dx massModel = inner(p,q) * dx preconModel = inner(grad(p),grad(q)) * dx mainOp = galerkinScheme([mainModel==0,DirichletBC(spcU,exact_u,1)]) gradOp = galerkinOperator(gradModel) divOp = galerkinOperator(divModel) massOp = galerkinScheme(massModel==0) preconOp = galerkinScheme(preconModel==0) velocity = spcU.interpolate([0,]*spcU.dimRange, name="velocity") pressure = spcP.interpolate([0], name="pressure") rhsVelo = velocity.copy() rhsPress = pressure.copy() r = rhsPress.copy() d = rhsPress.copy() precon = rhsPress.copy() xi = rhsVelo.copy()