Пример #1
0
def fdrake_mesh(request):
    mesh_name = request.param
    if mesh_name == "FiredrakeUnitIntervalMesh":
        return UnitIntervalMesh(100)
    elif mesh_name == "FiredrakeUnitSquareMesh":
        return UnitSquareMesh(10, 10)
    elif mesh_name == "FiredrakeUnitSquareMesh-order2":
        m = UnitSquareMesh(10, 10)
        fspace = VectorFunctionSpace(m, "CG", 2)
        coords = Function(fspace).interpolate(SpatialCoordinate(m))
        from firedrake.mesh import Mesh
        return Mesh(coords)
    elif mesh_name == "FiredrakeUnitCubeMesh":
        return UnitCubeMesh(5, 5, 5)
    elif mesh_name not in ("annulus.msh", "blob2d-order1-h4e-2.msh",
                           "blob2d-order1-h6e-2.msh",
                           "blob2d-order1-h8e-2.msh"):
        raise ValueError("Unexpected value for request.param")

    # Firedrake can't read in higher order meshes from gmsh,
    # so we can only use the order1 blobs
    from firedrake import Mesh
    fd_mesh = Mesh(mesh_name)
    fd_mesh.init()
    return fd_mesh
Пример #2
0
def run(problem, tensor, size_factor, degree):
    formname = problem.__name__
    cellname = 'cube' if tensor else 'simplex'
    PETSc.Sys.Print("%s: %s, degree=%d" % (formname, cellname, degree))
    num_cells = COMM_WORLD.size * max(1, 1e7 * size_factor / (degree + 1)**{'spectral': 4, 'coffee': 6}[args.mode])
    h = int(floor(cbrt(num_cells / COMM_WORLD.size)))
    w = int(floor(sqrt(num_cells / h)))
    d = int(round(num_cells / (w * h)))
    num_cells = w * d * h

    if tensor:
        mesh = ExtrudedMesh(UnitSquareMesh(w, d, quadrilateral=True), h)
    else:
        mesh = UnitCubeMesh(w, d, h)
    comm = mesh.comm
    J = problem(mesh, int(degree))

    # Warmup and allocate
    A = assemble(J, mat_type="matfree", form_compiler_parameters={'mode': args.mode})
    A.force_evaluation()
    Ap = A.petscmat
    x, y = Ap.createVecs()
    assert x.size == y.size
    num_dofs = x.size
    Ap.mult(x, y)
    stage = PETSc.Log.Stage("%s(%d) %s" % (formname, degree, cellname))
    with stage:
        assemble(J, mat_type="matfree", form_compiler_parameters={'mode': args.mode}, tensor=A)
        A.force_evaluation()
        Ap = A.petscmat
        for _ in range(num_matvecs):
            Ap.mult(x, y)

        parloop = parloop_event.getPerfInfo()
        matmult = matmult_event.getPerfInfo()
        assert parloop["count"] == 2 * num_matvecs
        assert matmult["count"] == num_matvecs
        parloop_time = comm.allreduce(parloop["time"], op=MPI.SUM) / (comm.size * num_matvecs)
        matmult_time = comm.allreduce(matmult["time"], op=MPI.SUM) / (comm.size * num_matvecs)

        matfree_overhead = (1 - parloop_time / matmult_time)
        PETSc.Sys.Print("Matrix-free action overhead: %.1f%%" % (matfree_overhead * 100,))

    if COMM_WORLD.rank == 0:
        header = not os.path.exists(filepath)
        data = {"num_cells": num_cells,
                "num_dofs": num_dofs,
                "num_procs": comm.size,
                "tsfc_mode": args.mode,
                "problem": formname,
                "cell_type": cellname,
                "degree": degree,
                "matmult_time": matmult_time,
                "parloop_time": parloop_time}
        df = pandas.DataFrame(data, index=[0])
        df.to_csv(filepath, index=False, mode='a', header=header)
Пример #3
0
    def setUp(self):
        """
        Create a function builder and input file.
        """
        self.mesh = UnitSquareMesh(10, 10)
        self.V = FunctionSpace(self.mesh, 'CG', 1)
        self.fb = FileBuilder(self.mesh, self.V)

        self.input = NamedTemporaryFile(mode='w+')
        self.fb.assign('path', self.input.name)
Пример #4
0
    def __init__(self):
        N = 5
        self.mesh = UnitSquareMesh(N, N)
        self.T0 = self.mesh.coordinates.copy(deepcopy=True)
        # random perturmabion
        h = 1 / N
        self.X = SpatialCoordinate(self.mesh)
        W = VectorFunctionSpace(self.mesh, "CG", 1)
        self.w = Function(W)
        vec = self.w.vector()
        np.random.seed(1)
        vec.set_local(
            np.random.uniform(-h / 3., h / 3., size=vec.get_local().shape))

        self.name = "missing name"
        self.bc = None
Пример #5
0
    def get_fdrake_mesh_and_h_from_par(mesh_par):
        if fdrake_mesh_name == "UnitInterval":
            assert dim == 1
            n = mesh_par
            fdrake_mesh = UnitIntervalMesh(n)
            h = 1 / n
        elif fdrake_mesh_name == "UnitSquare":
            assert dim == 2
            n = mesh_par
            fdrake_mesh = UnitSquareMesh(n, n)
            h = 1 / n
        elif fdrake_mesh_name == "UnitCube":
            assert dim == 3
            n = mesh_par
            fdrake_mesh = UnitCubeMesh(n, n, n)
            h = 1 / n
        elif fdrake_mesh_name in ("blob2d-order1", "blob2d-order4"):
            assert dim == 2
            if fdrake_mesh_name == "blob2d-order1":
                from firedrake import Mesh
                fdrake_mesh = Mesh(f"{fdrake_mesh_name}-h{mesh_par}.msh",
                                   dim=dim)
            else:
                from meshmode.mesh.io import read_gmsh
                from meshmode.interop.firedrake import export_mesh_to_firedrake
                mm_mesh = read_gmsh(f"{fdrake_mesh_name}-h{mesh_par}.msh",
                                    force_ambient_dim=dim)
                fdrake_mesh, _, _ = export_mesh_to_firedrake(mm_mesh)
            h = float(mesh_par)
        elif fdrake_mesh_name == "warp":
            from meshmode.mesh.generation import generate_warped_rect_mesh
            from meshmode.interop.firedrake import export_mesh_to_firedrake
            mm_mesh = generate_warped_rect_mesh(dim,
                                                order=4,
                                                nelements_side=mesh_par)
            fdrake_mesh, _, _ = export_mesh_to_firedrake(mm_mesh)
            h = 1 / mesh_par
        else:
            raise ValueError("fdrake_mesh_name not recognized")

        return (fdrake_mesh, h)
Пример #6
0
def regularization_form(r):
    mesh = UnitSquareMesh(2 ** r, 2 ** r)
    x = SpatialCoordinate(mesh)

    S = VectorFunctionSpace(mesh, "CG", 1)
    beta = 4.0
    reg_solver = RegularizationSolver(S, mesh, beta=beta, gamma=0.0, dx=dx)

    # Exact solution with free Neumann boundary conditions for this domain
    u_exact = Function(S)
    u_exact_component = cos(x[0] * pi * 2) * cos(x[1] * pi * 2)
    u_exact.interpolate(as_vector((u_exact_component, u_exact_component)))
    f = Function(S)
    theta = TestFunction(S)
    f_component = (1 + beta * 8 * pi * pi) * u_exact_component
    f.interpolate(as_vector((f_component, f_component)))
    rhs_form = inner(f, theta) * dx

    velocity = Function(S)
    rhs = assemble(rhs_form)
    reg_solver.solve(velocity, rhs)
    File("solution_vel_unitsquare.pvd").write(velocity)
    return norm(project(u_exact - velocity, S))
Пример #7
0
from firedrake import UnitSquareMesh, FunctionSpace, TrialFunction, TestFunction
from firedrake import SpatialCoordinate, dx, pi, sin, dot, grad, DirichletBC
from firedrake import assemble, Function, solve
import stat_fem
from stat_fem.covariance_functions import sqexp
try:
    import matplotlib.pyplot as plt
    makeplots = True
except ImportError:
    makeplots = False

# Set up base FEM, which solves Poisson's equation on a square mesh

nx = 101

mesh = UnitSquareMesh(nx - 1, nx - 1)
V = FunctionSpace(mesh, "CG", 1)

u = TrialFunction(V)
v = TestFunction(V)

f = Function(V)
x = SpatialCoordinate(mesh)
f.interpolate((8 * pi * pi) * sin(x[0] * pi * 2) * sin(x[1] * pi * 2))

a = (dot(grad(v), grad(u))) * dx
L = f * v * dx

bc = DirichletBC(V, 0., "on_boundary")

A = assemble(a, bcs=bc)
Пример #8
0
def heat(butcher_tableau):
    N = 4
    dt = Constant(1.0 / N)
    t = Constant(0.0)

    msh = UnitSquareMesh(N, N)
    deg = 2
    V = FunctionSpace(msh, "CG", deg)

    x, y = SpatialCoordinate(msh)

    uexact = t * (x + y)
    rhs = expand_derivatives(diff(uexact, t)) - div(grad(uexact))

    sols = []

    luparams = {
        "mat_type": "aij",
        "snes_type": "ksponly",
        "ksp_type": "preonly",
        "pc_type": "lu"
    }

    ranaLD = {
        "mat_type": "aij",
        "snes_type": "ksponly",
        "ksp_type": "gmres",
        "ksp_monitor": None,
        "pc_type": "python",
        "pc_python_type": "irksome.RanaLD",
        "aux": {
            "pc_type": "fieldsplit",
            "pc_fieldsplit_type": "multiplicative"
        }
    }
    per_field = {"ksp_type": "preonly", "pc_type": "gamg"}

    for s in range(butcher_tableau.num_stages):
        ranaLD["fieldsplit_%s" % (s, )] = per_field

    ranaDU = {
        "mat_type": "aij",
        "snes_type": "ksponly",
        "ksp_type": "gmres",
        "ksp_monitor": None,
        "pc_type": "python",
        "pc_python_type": "irksome.RanaDU",
        "aux": {
            "pc_type": "fieldsplit",
            "pc_fieldsplit_type": "multiplicative"
        }
    }

    for s in range(butcher_tableau.num_stages):
        ranaLD["fieldsplit_%s" % (s, )] = per_field

    params = [luparams, ranaLD, ranaDU]

    for solver_parameters in params:
        F, u, bc = Fubc(V, uexact, rhs)

        stepper = TimeStepper(F,
                              butcher_tableau,
                              t,
                              dt,
                              u,
                              bcs=bc,
                              solver_parameters=solver_parameters)
        stepper.advance()
        sols.append(u)

    errs = [errornorm(sols[0], uu) for uu in sols[1:]]
    return numpy.max(errs)
Пример #9
0
                               atol=CLOSE_ATOL)

    # Ensure the discretization and the firedrake function space reference element
    # agree on some basic properties
    finat_elt = fdrake_fspace.finat_element
    assert len(discr.groups) == 1
    assert discr.groups[0].order == finat_elt.degree
    assert discr.groups[0].nunit_dofs == finat_elt.space_dimension()


# }}}

# {{{ Boundary tags checking

bdy_tests = [
    (UnitSquareMesh(10, 10), [1, 2, 3, 4], [0, 0, 1, 1], [0.0, 1.0, 0.0, 1.0]),
    (UnitCubeMesh(5, 5, 5), [1, 2, 3, 4, 5,
                             6], [0, 0, 1, 1, 2,
                                  2], [0.0, 1.0, 0.0, 1.0, 0.0, 1.0]),
]


@pytest.mark.parametrize(
    "square_or_cube_mesh,bdy_ids,coord_indices,coord_values", bdy_tests)
@pytest.mark.parametrize("only_convert_bdy", (True, False))
def test_bdy_tags(square_or_cube_mesh, bdy_ids, coord_indices, coord_values,
                  only_convert_bdy):
    """
    Make sure the given boundary ids cover the converted mesh.
    Make sure that the given coordinate have the given value for the
    corresponding boundary tag (see :mod:`firedrake.utility_meshes`'s
Пример #10
0
 def make_mesh(nx, ny, nz, quadrilateral=False):
     return ExtrudedMesh(UnitSquareMesh(nx, ny,
                                        quadrilateral=quadrilateral),
                         nz,
                         layer_height=1.0 / nz)
Пример #11
0
plt.savefig("plots/RectangleMesh.png")


# -> SquareMesh
# -------------
# using SquareMesh (possible use of quadrilateral elements)
mesh = SquareMesh(nx, ny, L, quadrilateral=quad)
triplot(mesh)
plt.legend()
plt.savefig("plots/SquareMesh.png")


# -> UnitSquareMesh
# -----------------
# possible use of quadrilateral elements
mesh = UnitSquareMesh(nx, ny, quadrilateral=not quad)
triplot(mesh)
plt.legend()
plt.savefig("plots/UnitSquareMesh.png")


# -> PeriodicRectangleMesh
# ------------------------
# possible use of quadrilateral elements
mesh = PeriodicRectangleMesh(nx+1, ny, Lx, Ly)
triplot(mesh)
plt.legend()
plt.savefig("plots/PeriodicRectangleMesh.png")


# -> PeriodicSquareMesh
Пример #12
0
def main():
    # If can't import firedrake, do nothing
    #
    # filename MUST include "firedrake" (i.e. match *firedrake*.py) in order
    # to be run during CI
    try:
        import firedrake  # noqa : F401
    except ImportError:
        return 0

    from meshmode.interop.firedrake import build_connection_from_firedrake
    from firedrake import (UnitSquareMesh, FunctionSpace, SpatialCoordinate,
                           Function, cos)

    # Create a firedrake mesh and interpolate cos(x+y) onto it
    fd_mesh = UnitSquareMesh(10, 10)
    fd_fspace = FunctionSpace(fd_mesh, "DG", 2)
    spatial_coord = SpatialCoordinate(fd_mesh)
    fd_fntn = Function(fd_fspace).interpolate(cos(sum(spatial_coord)))

    # Make connections
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    fd_connection = build_connection_from_firedrake(actx, fd_fspace)
    fd_bdy_connection = \
        build_connection_from_firedrake(actx,
                                        fd_fspace,
                                        restrict_to_boundary="on_boundary")

    # Plot the meshmode meshes that the connections connect to
    import matplotlib.pyplot as plt
    from meshmode.mesh.visualization import draw_2d_mesh
    fig, (ax1, ax2) = plt.subplots(1, 2)
    ax1.set_title("FiredrakeConnection")
    plt.sca(ax1)
    draw_2d_mesh(fd_connection.discr.mesh,
                 draw_vertex_numbers=False,
                 draw_element_numbers=False,
                 set_bounding_box=True)
    ax2.set_title("FiredrakeConnection 'on_boundary'")
    plt.sca(ax2)
    draw_2d_mesh(fd_bdy_connection.discr.mesh,
                 draw_vertex_numbers=False,
                 draw_element_numbers=False,
                 set_bounding_box=True)
    plt.show()

    # Plot fd_fntn using unrestricted FiredrakeConnection
    from meshmode.discretization.visualization import make_visualizer
    discr = fd_connection.discr
    vis = make_visualizer(actx, discr, discr.groups[0].order + 3)
    field = fd_connection.from_firedrake(fd_fntn, actx=actx)

    fig = plt.figure()
    ax1 = fig.add_subplot(1, 2, 1, projection="3d")
    ax1.set_title("cos(x+y) in\nFiredrakeConnection")
    vis.show_scalar_in_matplotlib_3d(field, do_show=False)

    # Now repeat using FiredrakeConnection restricted to "on_boundary"
    bdy_discr = fd_bdy_connection.discr
    bdy_vis = make_visualizer(actx, bdy_discr, bdy_discr.groups[0].order + 3)
    bdy_field = fd_bdy_connection.from_firedrake(fd_fntn, actx=actx)

    ax2 = fig.add_subplot(1, 2, 2, projection="3d")
    plt.sca(ax2)
    ax2.set_title("cos(x+y) in\nFiredrakeConnection 'on_boundary'")
    bdy_vis.show_scalar_in_matplotlib_3d(bdy_field, do_show=False)

    import matplotlib.cm as cm
    fig.colorbar(cm.ScalarMappable())
    plt.show()
    np.testing.assert_allclose(lex_sorted_mm_verts, lex_sorted_fdrake_verts.T,
                               atol=CLOSE_ATOL)

    # Ensure the discretization and the firedrake function space reference element
    # agree on some basic properties
    finat_elt = fdrake_fspace.finat_element
    assert len(discr.groups) == 1
    assert discr.groups[0].order == finat_elt.degree
    assert discr.groups[0].nunit_dofs == finat_elt.space_dimension()

# }}}


# {{{ Boundary tags checking

bdy_tests = [(UnitSquareMesh(10, 10),
             [1, 2, 3, 4],
             [0, 0, 1, 1],
             [0.0, 1.0, 0.0, 1.0]),
             (UnitCubeMesh(5, 5, 5),
              [1, 2, 3, 4, 5, 6],
              [0, 0, 1, 1, 2, 2],
              [0.0, 1.0, 0.0, 1.0, 0.0, 1.0]),
             ]


@pytest.mark.parametrize("square_or_cube_mesh,bdy_ids,coord_indices,coord_values",
                         bdy_tests)
@pytest.mark.parametrize("only_convert_bdy", (True, False))
def test_bdy_tags(square_or_cube_mesh, bdy_ids, coord_indices, coord_values,
                  only_convert_bdy):
Пример #14
0
error_threshold = 1e-3

if cell_type == "quad":
    quadrilateral = True
elif cell_type == "tria":
    quadrilateral = False
else:
    raise ValueError("Cell type not supported")

# building reference solution
p = 1
initial_dt = 0.00005

# determining dt as f(p) in mesh
degrees = [5]
mesh = UnitSquareMesh(40, 40, quadrilateral=quadrilateral)
mh = MeshHierarchy(mesh, 3)

# determine maximum stable timestep with error < error_threshold
dts = np.zeros((len(mh) - 1, len(degrees)))

# construct reference solution
ref = solver_CG(mh[-1],
                el=cell_type,
                space=space,
                deg=p,
                T=0.50,
                dt=initial_dt)
V_fine = _build_space(mh[-1], cell_type, space, p)

# step to increase timestep (step << dt)
Пример #15
0
def test_replace_subject(subject_type, replacement_type):

    # ------------------------------------------------------------------------ #
    # Only certain combinations of options are valid
    # ------------------------------------------------------------------------ #

    if subject_type == 'vector' and replacement_type != 'vector':
        return True
    elif replacement_type == 'vector' and subject_type != 'vector':
        return True

    # ------------------------------------------------------------------------ #
    # Set up
    # ------------------------------------------------------------------------ #

    # Some basic labels
    foo_label = Label("foo")
    bar_label = Label("bar")

    # Create mesh, function space and forms
    n = 3
    mesh = UnitSquareMesh(n, n)
    V0 = FunctionSpace(mesh, "DG", 0)
    V1 = FunctionSpace(mesh, "CG", 1)
    V2 = VectorFunctionSpace(mesh, "DG", 0)
    Vmixed = MixedFunctionSpace((V0, V1))

    idx = None

    # ------------------------------------------------------------------------ #
    # Choose subject
    # ------------------------------------------------------------------------ #

    if subject_type == 'normal':
        V = V0
    elif subject_type == 'mixed':
        V = Vmixed
        if replacement_type == 'normal':
            idx = 0
    elif subject_type == 'vector':
        V = V2
    else:
        raise ValueError

    the_subject = Function(V)
    not_subject = Function(V)
    test = TestFunction(V)

    form_1 = inner(the_subject, test)*dx
    form_2 = inner(not_subject, test)*dx

    term_1 = foo_label(subject(form_1, the_subject))
    term_2 = bar_label(form_2)
    labelled_form = term_1 + term_2

    # ------------------------------------------------------------------------ #
    # Choose replacement
    # ------------------------------------------------------------------------ #

    if replacement_type == 'normal':
        V = V1
    elif replacement_type == 'mixed':
        V = Vmixed
        if subject_type != 'mixed':
            idx = 0
    elif replacement_type == 'vector':
        V = V2
    elif replacement_type == 'tuple':
        V = Vmixed
    else:
        raise ValueError

    the_replacement = Function(V)

    if replacement_type == 'tuple':
        the_replacement = TrialFunctions(Vmixed)
        if subject_type == 'normal':
            idx = 0

    # ------------------------------------------------------------------------ #
    # Test replace_subject
    # ------------------------------------------------------------------------ #

    labelled_form = labelled_form.label_map(
        lambda t: t.has_label(subject),
        map_if_true=replace_subject(the_replacement, idx=idx)
    )
Пример #16
0
    rhs, div, assemble, File, solve

# Print log messages only from the root process in parallel
# parameters["std_out_all_processes"] = False;

# Set parameter values
T = 10.0
Re = 3000.0
Umax = 1.0
C = 0.3

N = int((Re**(0.75)) * 2.0)

dt = C * (1.0 / N) / Umax

mesh = UnitSquareMesh(N, N)

# Define function spaces (P2-P1)
V = VectorFunctionSpace(mesh, "Lagrange", 2)
Q = FunctionSpace(mesh, "Lagrange", 1)

# Define trial and test functions
u = TrialFunction(V)
p = TrialFunction(Q)
v = TestFunction(V)
q = TestFunction(Q)

# Define time-dependent pressure boundary condition
#p_in = Expression("sin(3.0*t)", t=0.0)

u_in = Expression(('1.0*(x[1]>0.5)+0.5*(x[1]<=0.5)', '0.0'))
Пример #17
0
        form, parameters=parameters)[0]

    indices = IndexDict(
        {idx: sympy.symbols(name)
         for idx, name in index_names})

    expr = expression(impero_kernel.tree,
                      impero_kernel.temporaries,
                      indices,
                      top=True)
    p1 = sympy.symbols("p") + 1
    '''Currently assume p+1 quad points in each direction.'''
    return expr.subs([(i, p1) for i in indices.values()]).expand()


m = ExtrudedMesh(UnitSquareMesh(2, 2, quadrilateral=True), 2)

mass = form.mass(m, 6)
poisson = form.poisson(m, 6)
hyperelasticity = form.hyperelasticity(m, 6)
curl_curl = form.curl_curl(m, 6)

parameters = firedrake.parameters['form_compiler'].copy()
parameters['return_impero'] = True
parameters['mode'] = 'spectral'

for mode, action in (("assembly", False), ("action", True)):
    print(mode)
    print("  mass: ", complexity(mass, parameters, action))
    print("  laplacian: ", complexity(poisson, parameters, action))
    print("  hyperelasticity:", complexity(hyperelasticity, parameters,
Пример #18
0
 def setUp(self):
     mesh = UnitSquareMesh(100, 100)
     V = FunctionSpace(mesh, 'CG', 1)
     self.factory = FunctionBuilderFactory(mesh=mesh, V=V)
Пример #19
0
def main():
    # make function space and function
    dim = 2  # 2 or 3
    order = 1

    logger.info(f"building {dim}D source and solution exprs")
    if dim == 2:
        m = UnitSquareMesh(32, 32)
    elif dim == 3:
        m = UnitCubeMesh(16, 16, 16)
    else:
        raise ValueError("dim must be 2 or 3, not %s" % dim)
    # get spatial coordinate, shifted so that [0,1]^2 -> [-0.5,0.5]^2
    xx = SpatialCoordinate(m)
    shifted_xx = as_tensor([xx_i - 0.5 for xx_i in xx])
    norm2 = sum([xx_i * xx_i for xx_i in shifted_xx])
    alpha = 10
    source_expr = -(4 * alpha**2 * norm2 - 2 * dim * alpha) * exp(
        -alpha * norm2)
    sol_expr = exp(-alpha * norm2)

    logger.info("source_expr : %s" % source_expr)
    logger.info("sol_expr : %s" % sol_expr)

    logger.info(f"Building FunctionSpace of order {order}")
    fspace = FunctionSpace(m, 'DG', order)
    logger.info("interpolating source and solution")
    source = Function(fspace).interpolate(source_expr)
    sol = Function(fspace).interpolate(sol_expr)

    from sumpy.kernel import LaplaceKernel
    kernel = LaplaceKernel(m.geometric_dimension())

    # We could set to a custom group factory if we wanted to,
    # defaults to recursive nodes with 'lgl' nodes
    #
    # from meshmode.discretization.poly_element import (
    #     PolynomialWarpAndBlendGroupFactory)
    # grp_factory = PolynomialWarpAndBlendGroupFactory(order)
    grp_factory = None

    # Build VolumePotential external operator
    cl_ctx = cl.create_some_context()
    queue = cl.CommandQueue(cl_ctx)
    potential_data = {
        'kernel': kernel,
        'kernel_type': "Laplace",
        'cl_ctx': cl_ctx,
        'queue': queue,
        'nlevels': 6,
        'm_order': 20,
        'dataset_filename': f"laplace-order{order}-{dim}D.hdf5",
        'grp_factory': grp_factory,
        'root_extent': 2,
        'table_compute_method': "DrosteSum",
        'table_kwargs': {
            'force_recompute': False,
            'n_brick_quad_points': 100,
            'adaptive_level': False,
            'use_symmetry': True,
            'alpha': 0.1,
            'nlevels': 15,
        },
        'fmm_kwargs': {},
    }

    logger.info("Creating volume potential")
    # pot = VolumePotential(source, function_space=source.function_space(), operator_data=potential_data)

    # logger.info("Evaluating potential and assembling L^2 Error")
    # ell2_difference = sqrt(assemble(inner(pot - sol, pot - sol) * dx))

    # print("L^2 difference: %e" % ell2_difference)
    print("interpolation error: %e" % errornorm(sol_expr, sol))