Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
def forms(arguments, coefficients):
    v, u = arguments
    c, f = coefficients
    n = FacetNormal(triangle)
    a = u * v * dx
    L = f * v * dx
    b = u * v * dx(0) + inner(c * grad(u), grad(v)) * \
        dx(1) + dot(n, grad(u)) * v * ds + f * v * dx
    return (a, L, b)
Ejemplo n.º 3
0
def test_facet_normals(cell_type):
    """Test that FacetNormal is outward facing"""
    for count in range(5):
        mesh = unit_cell(cell_type)
        tdim = mesh.topology.dim

        V = VectorFunctionSpace(mesh, ("Lagrange", 1))
        normal = FacetNormal(mesh)
        v = Function(V)

        map_f = mesh.topology.index_map(tdim - 1)
        num_facets = map_f.size_local + map_f.num_ghosts
        indices = np.arange(0, num_facets)
        values = np.arange(0, num_facets, dtype=np.intc)
        marker = MeshTags(mesh, tdim - 1, indices, values)

        # For each facet, check that the inner product of the normal and
        # the vector that has a positive normal component on only that
        # facet is positive
        for i in range(num_facets):
            if cell_type == CellType.interval:
                co = mesh.geometry.x[i]
                v.interpolate(lambda x: x[0] - co[0])
            if cell_type == CellType.triangle:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away
                # from `co` so that there is no normal component on two
                # edges and the integral over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 2, (x[1] - co[1]) / 2))
            elif cell_type == CellType.tetrahedron:
                co = mesh.geometry.x[i]
                # Vector function that is zero at `co` and points away
                # from `co` so that there is no normal component on
                # three faces and the integral over the other edge is 1
                v.interpolate(lambda x: ((x[0] - co[0]) / 3, (x[1] - co[1]) / 3, (x[2] - co[2]) / 3))
            elif cell_type == CellType.quadrilateral:
                # function that is 0 on one edge and points away from
                # that edge so that there is no normal component on
                # three edges
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 2 else 0 * x[j] for j in range(2)))
            elif cell_type == CellType.hexahedron:
                # function that is 0 on one face and points away from
                # that face so that there is no normal component on five
                # faces
                v.interpolate(lambda x: tuple(x[j] - i % 2 if j == i // 3 else 0 * x[j] for j in range(3)))

            # assert that the integrals these functions dotted with the
            # normal over a face is 1 on one face and 0 on the others
            ones = 0
            for j in range(num_facets):
                a = inner(v, normal) * ds(subdomain_data=marker, subdomain_id=j)
                result = fem.assemble_scalar(a)
                if np.isclose(result, 1):
                    ones += 1
                else:
                    assert np.isclose(result, 0)
            assert ones == 1
    def __init__(self, mesh, k: int, omega, c, c0, lumped):
        P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), k)
        self.V = FunctionSpace(mesh, P)
        self.u, self.v = Function(self.V), Function(self.V)
        self.g1 = Function(self.V)
        self.g2 = Function(self.V)
        self.omega = omega
        self.c = c
        self.c0 = c0

        n = FacetNormal(mesh)

        # Pieces for plane wave incident field
        x = ufl.geometry.SpatialCoordinate(mesh)
        cos_wave = ufl.cos(self.omega / self.c0 * x[0])
        sin_wave = ufl.sin(self.omega / self.c0 * x[0])

        plane_wave = self.g1 * cos_wave + self.g2 * sin_wave

        dv, p = TrialFunction(self.V), TestFunction(self.V)
        self.L1 = - inner(grad(self.u), grad(p)) * dx(degree=k) \
            - (1 / self.c) * inner(self.v, p) * ds \
            - (1 / self.c**2) * (-self.omega**2) * inner(plane_wave, p) * dx \
            - inner(grad(plane_wave), grad(p)) * dx \
            + inner(dot(grad(plane_wave), n), p) * ds

        # Vector to be re-used for assembly
        self.b = None

        # TODO: precompile/pre-process Form L

        self.lumped = lumped
        if self.lumped:
            a = (1 / self.c**2) * p * dx(degree=k)
            self.M = dolfinx.fem.assemble_vector(a)
            self.M.ghostUpdate(addv=PETSc.InsertMode.ADD,
                               mode=PETSc.ScatterMode.REVERSE)
        else:
            a = (1 / self.c**2) * inner(dv, p) * dx(degree=k)
            M = dolfinx.fem.assemble_matrix(a)
            M.assemble()
            self.solver = PETSc.KSP().create(mesh.mpi_comm())
            opts = PETSc.Options()
            opts["ksp_type"] = "cg"
            opts["ksp_rtol"] = 1.0e-8
            self.solver.setFromOptions()
            self.solver.setOperators(M)
Ejemplo n.º 5
0
    def __init__(self, args, tc, metadata):
        self.has_analytic_solution = False
        self.problem_code = 'FACB'
        super(Problem, self).__init__(args, tc, metadata)

        self.name = 'test on real mesh'
        self.status_functional_str = 'not selected'

        # input parameters
        self.factor = args.factor
        self.scale_factor.append(self.factor)

        self.nu = 0.001 * args.nufactor  # kinematic viscosity

        # Import gmsh mesh
        self.compatible_meshes = ['bench3D_1', 'bench3D_2', 'bench3D_3']
        if args.mesh not in self.compatible_meshes:
            exit('Bad mesh, should be some from %s' %
                 str(self.compatible_meshes))

        self.mesh = Mesh("meshes/" + args.mesh + ".xml")
        self.cell_function = MeshFunction(
            "size_t", self.mesh,
            "meshes/" + args.mesh + "_physical_region.xml")
        self.facet_function = MeshFunction(
            "size_t", self.mesh, "meshes/" + args.mesh + "_facet_region.xml")
        self.dsIn = Measure("ds",
                            subdomain_id=2,
                            subdomain_data=self.facet_function)
        self.dsOut = Measure("ds",
                             subdomain_id=3,
                             subdomain_data=self.facet_function)
        self.dsWall = Measure("ds",
                              subdomain_id=1,
                              subdomain_data=self.facet_function)
        self.dsCyl = Measure("ds",
                             subdomain_id=5,
                             subdomain_data=self.facet_function)
        self.normal = FacetNormal(self.mesh)
        print("Mesh name: ", args.mesh, "    ", self.mesh)
        print("Mesh norm max: ", self.mesh.hmax())
        print("Mesh norm min: ", self.mesh.hmin())

        self.actual_time = None
        self.v_in = None
Ejemplo n.º 6
0
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})

    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)

    # Calculate error
    M = (u_exact - uh)**2 * dx
    M = fem.Form(M)

    error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM)
    assert np.absolute(error) < 1.0e-14
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
                     has_petsc_complex, solve)
from dolfinx.fem.assemble import assemble_scalar
from dolfinx.io import XDMFFile
from ufl import FacetNormal, TestFunction, TrialFunction, dx, grad, inner

# wavenumber
k0 = 4 * np.pi

# approximation space polynomial degree
deg = 1

# number of elements in each direction of mesh
n_elem = 128

mesh = UnitSquareMesh(MPI.COMM_WORLD, n_elem, n_elem)
n = FacetNormal(mesh)

# Source amplitude
if has_petsc_complex:
    A = 1 + 1j
else:
    A = 1

# Test and trial function space
V = FunctionSpace(mesh, ("Lagrange", deg))

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Function(V)
f.interpolate(lambda x: A * k0**2 * np.cos(k0 * x[0]) * np.cos(k0 * x[1]))
Ejemplo n.º 9
0
# \begin{align*}
# u(x) = \left(\frac{1}{2}(x^2 + y^2) - \frac{1}{3}(x^3 - y^3)\right) + 1
# \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>
Ejemplo n.º 10
0
 def b(tau_S, v):
     n = FacetNormal(mesh)
     return inner(tau_S, grad(grad(v))) * dx \
         - ufl.dot(ufl.dot(tau_S('+'), n('+')), n('+')) * jump(grad(v), n) * dS \
         - ufl.dot(ufl.dot(tau_S, n), n) * ufl.dot(grad(v), n) * ds
Ejemplo n.º 11
0
# Last changed: 2007-07-15
#
# 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
Ejemplo n.º 12
0
    def __init__(self, args, tc, metadata):
        self.has_analytic_solution = False
        self.problem_code = 'REAL'
        super(Problem, self).__init__(args, tc, metadata)

        self.name = 'test on real mesh'
        self.status_functional_str = 'outflow/inflow'
        self.last_inflow = 0

        # time settings
        self.itp_lengths = {
            1: 1.0,
            2: 0.9375,
        }
        self.cycle_length = self.itp_lengths[self.args.itp]

        # input parameters
        self.nu = self.args.nu  # kinematic viscosity
        self.factor = args.factor
        self.metadata['factor'] = self.factor
        self.scale_factor.append(self.factor)

        self.tc.start('mesh')
        # Import mesh
        try:
            self.mesh, self.facet_function = super(Problem,
                                                   self).loadMesh(args.mesh)
            info("Mesh name: " + args.mesh + "    " + str(self.mesh))
            f_ini = open('meshes/' + args.mesh + '.ini', 'r')
            reader = csv.reader(f_ini, delimiter=' ', escapechar='\\')
        except (EnvironmentError, RuntimeError):
            print(
                'Unable to open mesh.hdf5 or mesh.ini file. Check if the mesh was prepared to be used '
                'with \"real\" problem.')
            exit(1)

        # load inflows and outflows (interfaces) from mesh.ini file
        obj = None
        self.interfaces = []
        for row in reader:
            if not row:
                pass
            elif row[0] == 'volume':
                self.mesh_volume = float(row[1])
            elif row[0] == 'in':
                if obj is not None:
                    self.interfaces.append(obj)
                obj = {'inflow': True, 'number': row[1]}
            elif row[0] == 'out':
                if obj is not None:
                    self.interfaces.append(obj)
                obj = {'inflow': False, 'number': row[1]}
            else:
                if len(row) == 2:  # scalar values
                    obj[row[0]] = row[1]
                else:  # vector values
                    obj[row[0]] = [float(f) for f in row[1:]]
        self.interfaces.append(obj)
        f_ini.close()
        self.tc.end('mesh')

        # collect inflows and outflows into separate lists
        self.outflow_area = 0
        self.inflows = []
        self.outflows = []
        for obj in self.interfaces:
            if not obj['inflow']:
                self.outflow_area += float(obj['S'])
                self.outflows.append(obj)
            else:
                self.inflows.append(obj)
        info('Outflow area: %f' % self.outflow_area)

        # self.dsWall = Measure("ds", subdomain_id=1, subdomain_data=self.facet_function)
        self.normal = FacetNormal(self.mesh)

        # generate measures, collect measure lists
        self.inflow_measures = []
        for obj in self.interfaces:
            obj['measure'] = Measure("ds",
                                     subdomain_id=int(obj['number']),
                                     subdomain_data=self.facet_function)
            if obj['inflow']:
                self.inflow_measures.append(obj['measure'])
            else:
                self.outflow_measures.append(obj['measure'])

        self.listDict.update({
            'outflow': {
                'list': [],
                'name': 'outflow rate',
                'abrev': 'OUT',
                'slist': []
            },
            'inflow': {
                'list': [],
                'name': 'inflow rate',
                'abrev': 'IN',
                'slist': []
            },
            'oiratio': {
                'list': [],
                'name': 'outflow/inflow ratio (mass conservation)',
                'abrev': 'O/I',
                'slist': []
            },
        })
        for obj in self.outflows:
            n = obj['number']
            self.listDict.update({
                'outflow' + n: {
                    'list': [],
                    'name': 'outflow rate ' + n,
                    'abrev': 'OUT' + n,
                    'slist': []
                }
            })
        self.can_force_outflow = True
Ejemplo n.º 13
0
#
# Author: Marie Rognes
# Modified by: Martin Sandve Alnes
# Date: 2009-02-12
#
from ufl import (FacetNormal, FiniteElement, TestFunctions, TrialFunctions,
                 div, dot, ds, dx, tetrahedron)

cell = tetrahedron
RT = FiniteElement("Raviart-Thomas", cell, 1)
DG = FiniteElement("DG", cell, 0)
MX = RT * DG

(u, p) = TrialFunctions(MX)
(v, q) = TestFunctions(MX)

n = FacetNormal(cell)

a0 = (dot(u, v) + div(u) * q + div(v) * p) * dx
a1 = (dot(u, v) + div(u) * q + div(v) * p) * dx - p * dot(v, n) * ds

forms = [a0, a1]
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
def test_div_grad_then_integrate_over_cells_and_boundary():

    # Define 2D geometry
    n = 10
    mesh = RectangleMesh(
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([2.0, 3.0, 0.0])], 2 * n, 3 * n)

    x, y = SpatialCoordinate(mesh)
    xs = 0.1 + 0.8 * x / 2  # scaled to be within [0.1,0.9]
    #    ys = 0.1 + 0.8 * y / 3  # scaled to be within [0.1,0.9]
    n = FacetNormal(mesh)

    # Define list of expressions to test, and configure accuracies
    # these expressions are known to pass with.  The reason some
    # functions are less accurately integrated is likely that the
    # default choice of quadrature rule is not perfect
    F_list = []

    def reg(exprs, acc=10):
        for expr in exprs:
            F_list.append((expr, acc))

    # FIXME: 0*dx and 1*dx fails in the ufl-ffcx-jit framework somewhere
    # reg([Constant(0.0, cell=cell)])
    # reg([Constant(1.0, cell=cell)])
    monomial_list = [x**q for q in range(2, 6)]
    reg(monomial_list)
    reg([2.3 * p + 4.5 * q for p in monomial_list for q in monomial_list])
    reg([xs**xs])
    reg(
        [xs**(xs**2)], 8
    )  # Note: Accuracies here are from 1D case, not checked against 2D results.
    reg([xs**(xs**3)], 6)
    reg([xs**(xs**4)], 2)
    # Special functions:
    reg([atan(xs)], 8)
    reg([sin(x), cos(x), exp(x)], 5)
    reg([ln(xs), pow(x, 2.7), pow(2.7, x)], 3)
    reg([asin(xs), acos(xs)], 1)
    reg([tan(xs)], 7)

    # To handle tensor algebra, make an x dependent input tensor
    # xx and square all expressions
    def reg2(exprs, acc=10):
        for expr in exprs:
            F_list.append((inner(expr, expr), acc))

    xx = as_matrix([[2 * x**2, 3 * x**3], [11 * x**5, 7 * x**4]])
    xxs = as_matrix([[2 * xs**2, 3 * xs**3], [11 * xs**5, 7 * xs**4]])
    x3v = as_vector([3 * x**2, 5 * x**3, 7 * x**4])
    cc = as_matrix([[2, 3], [4, 5]])
    reg2(
        [xx]
    )  # TODO: Make unit test for UFL from this, results in listtensor with free indices
    reg2([x3v])
    reg2([cross(3 * x3v, as_vector([-x3v[1], x3v[0], x3v[2]]))])
    reg2([xx.T])
    reg2([tr(xx)])
    reg2([det(xx)])
    reg2([dot(xx, 0.1 * xx)])
    reg2([outer(xx, xx.T)])
    reg2([dev(xx)])
    reg2([sym(xx)])
    reg2([skew(xx)])
    reg2([elem_mult(7 * xx, cc)])
    reg2([elem_div(7 * xx, xx + cc)])
    reg2([elem_pow(1e-3 * xxs, 1e-3 * cc)])
    reg2([elem_pow(1e-3 * cc, 1e-3 * xx)])
    reg2([elem_op(lambda z: sin(z) + 2, 0.03 * xx)], 2)  # pretty inaccurate...

    # FIXME: Add tests for all UFL operators:
    # These cause discontinuities and may be harder to test in the
    # above fashion:
    # 'inv', 'cofac',
    # 'eq', 'ne', 'le', 'ge', 'lt', 'gt', 'And', 'Or', 'Not',
    # 'conditional', 'sign',
    # 'jump', 'avg',
    # 'LiftingFunction', 'LiftingOperator',

    # FIXME: Test other derivatives: (but algorithms for operator
    # derivatives are the same!):
    # 'variable', 'diff',
    # 'Dx', 'grad', 'div', 'curl', 'rot', 'Dn', 'exterior_derivative',

    # Run through all operators defined above and compare integrals
    debug = 0
    if debug:
        F_list = F_list[1:]

    for F, acc in F_list:
        if debug:
            print('\n', "F:", str(F))

        # Integrate over domain and its boundary
        int_dx = assemble(div(grad(F)) * dx(mesh))  # noqa
        int_ds = assemble(dot(grad(F), n) * ds(mesh))  # noqa

        if debug:
            print(int_dx, int_ds)

        # Compare results. Using custom relative delta instead of
        # decimal digits here because some numbers are >> 1.
        delta = min(abs(int_dx), abs(int_ds)) * 10**-acc
        assert int_dx - int_ds <= delta
Ejemplo n.º 16
0
    def __init__(self, args, tc, metadata):
        self.has_analytic_solution = True
        self.problem_code = 'WCYL'
        super(Problem, self).__init__(args, tc, metadata)

        self.tc.init_watch('assembleSol', 'Assembled analytic solution', True)
        self.tc.init_watch('analyticP', 'Analytic pressure', True)
        self.tc.init_watch('analyticVnorms',
                           'Computed analytic velocity norms', True)
        self.tc.init_watch('errorP', 'Computed pressure error', True)
        self.tc.init_watch('errorForce', 'Computed force error', True)
        self.tc.init_watch('computePG', 'Computed pressure gradient', True)

        self.name = 'womersley_cylinder'
        self.status_functional_str = 'last H1 velocity error'

        # input parameters
        self.ic = args.ic
        self.factor = args.factor
        self.metadata['factor'] = self.factor
        self.scale_factor.append(self.factor)

        # fixed parameters (used in analytic solution and in BC)
        self.nu = 3.71 * self.args.nufactor  # kinematic viscosity
        self.R = 5.0  # cylinder radius

        self.mesh_volume = pi * 25. * 20.

        # Import gmsh mesh
        self.tc.start('mesh')
        self.mesh, self.facet_function = super(Problem,
                                               self).loadMesh(args.mesh)
        self.dsIn = Measure("ds",
                            subdomain_id=2,
                            subdomain_data=self.facet_function)
        self.dsOut = Measure("ds",
                             subdomain_id=3,
                             subdomain_data=self.facet_function)
        self.dsWall = Measure("ds",
                              subdomain_id=1,
                              subdomain_data=self.facet_function)
        self.normal = FacetNormal(self.mesh)
        print("Mesh name: ", args.mesh, "    ", self.mesh)
        print("Mesh norm max: ", self.mesh.hmax())
        print("Mesh norm min: ", self.mesh.hmin())
        self.tc.end('mesh')

        self.sol_p = None
        self.last_analytic_pressure_norm = None
        self.v_in = None
        self.area = None

        choose_note = {1.0: '', 0.1: 'nuL10', 0.01: 'nuL100', 10.0: 'nuH10'}
        self.precomputed_filename = args.mesh + choose_note[self.args.nufactor]
        print('chosen filename for precomputed solution',
              self.precomputed_filename)

        # partial Bessel functions and coefficients
        self.bessel_parabolic = None
        self.bessel_real = []
        self.bessel_complex = []
        self.coefs_exp = [-8, -6, -4, -2, 2, 4, 6, 8]

        self.listDict.update({
            'u_H1w': {
                'list': [],
                'name': 'corrected velocity H1 error on wall',
                'abrev': 'CE_H1w',
                'scale': self.scale_factor,
                'relative': 'av_norm_H1w',
                'slist': []
            },
            'u2H1w': {
                'list': [],
                'name': 'tentative velocity H1 error on wall',
                'abrev': 'TE_H1w',
                'scale': self.scale_factor,
                'relative': 'av_norm_H1w',
                'slist': []
            },
            'av_norm_H1w': {
                'list': [],
                'name': 'analytic velocity H1 norm on wall',
                'abrev': 'AVN_H1w'
            },
            'a_force_wall': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AF'
            },
            'a_force_wall_normal': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AFN'
            },
            'a_force_wall_shear': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AFS'
            },
            'force_wall': {
                'list': [],
                'name': 'force error on wall',
                'abrev': 'FE',
                'relative': 'a_force_wall',
                'slist': []
            },
            'force_wall_normal': {
                'list': [],
                'name': 'normal force error on wall',
                'abrev': 'FNE',
                'relative': 'a_force_wall',
                'slist': []
            },
            'force_wall_shear': {
                'list': [],
                'name': 'shear force error on wall',
                'abrev': 'FSE',
                'relative': 'a_force_wall',
                'slist': []
            },
        })
Ejemplo n.º 17
0
def _compileUFL(integrands, form, *args, tempVars=True):
    if isinstance(form, Equation):
        form = form.lhs - form.rhs
    if not isinstance(form, Form):
        raise ValueError("ufl.Form or ufl.Equation expected.")

    # added for dirichlet treatment same as conservationlaw model
    dirichletBCs = [arg for arg in args if isinstance(arg, DirichletBC)]

    uflExpr = [form] + [bc.ufl_value for bc in dirichletBCs]
    if len(form.arguments()) < 2:
        raise ValueError(
            "Integrands model requires form with at least two arguments.")

    x = SpatialCoordinate(form.ufl_cell())
    n = FacetNormal(form.ufl_cell())

    cellVolume = CellVolume(form.ufl_cell())
    maxCellEdgeLength = MaxCellEdgeLength(form.ufl_cell())
    minCellEdgeLength = MinCellEdgeLength(form.ufl_cell())

    facetArea = FacetArea(form.ufl_cell())
    maxFacetEdgeLength = MaxFacetEdgeLength(form.ufl_cell())
    minFacetEdgeLength = MinFacetEdgeLength(form.ufl_cell())

    phi, u = form.arguments()
    ubar = Coefficient(u.ufl_function_space())

    derivatives = gatherDerivatives(form, [phi, u])

    derivatives_phi = derivatives[0]
    derivatives_u = derivatives[1]
    derivatives_ubar = map_expr_dags(Replacer({u: ubar}), derivatives_u)

    try:
        integrands.field = u.ufl_function_space().field
    except AttributeError:
        pass

    integrals = splitForm(form, [phi])

    dform = apply_derivatives(derivative(action(form, ubar), ubar, u))
    linearizedIntegrals = splitForm(dform, [phi, u])

    if not set(
            integrals.keys()) <= {'cell', 'exterior_facet', 'interior_facet'}:
        raise Exception('unknown integral encountered in ' +
                        str(set(integrals.keys())) + '.')

    if 'cell' in integrals.keys():
        arg = Variable(integrands.domainValueTuple, 'u')

        predefined = {
            derivatives_u[i]: arg[i]
            for i in range(len(derivatives_u))
        }
        predefined[x] = integrands.spatialCoordinate('x')
        predefined[cellVolume] = integrands.cellVolume()
        predefined[maxCellEdgeLength] = maxEdgeLength(
            integrands.cellGeometry())
        predefined[minCellEdgeLength] = minEdgeLength(
            integrands.cellGeometry())
        integrands.predefineCoefficients(predefined, False)
        integrands.interior = generateUnaryCode(predefined,
                                                derivatives_phi,
                                                integrals['cell'],
                                                tempVars=tempVars)

        predefined = {
            derivatives_ubar[i]: arg[i]
            for i in range(len(derivatives_u))
        }
        predefined[x] = integrands.spatialCoordinate('x')
        predefined[cellVolume] = integrands.cellVolume()
        predefined[maxCellEdgeLength] = maxEdgeLength(
            integrands.cellGeometry())
        predefined[minCellEdgeLength] = minEdgeLength(
            integrands.cellGeometry())
        integrands.predefineCoefficients(predefined, False)
        integrands.linearizedInterior = generateUnaryLinearizedCode(
            predefined,
            derivatives_phi,
            derivatives_u,
            linearizedIntegrals.get('cell'),
            tempVars=tempVars)

    if 'exterior_facet' in integrals.keys():
        arg = Variable(integrands.domainValueTuple, 'u')

        predefined = {
            derivatives_u[i]: arg[i]
            for i in range(len(derivatives_u))
        }
        predefined[x] = integrands.spatialCoordinate('x')
        predefined[n] = integrands.facetNormal('x')
        predefined[cellVolume] = integrands.cellVolume()
        predefined[maxCellEdgeLength] = maxEdgeLength(
            integrands.cellGeometry())
        predefined[minCellEdgeLength] = minEdgeLength(
            integrands.cellGeometry())
        predefined[facetArea] = integrands.facetArea()
        predefined[maxFacetEdgeLength] = maxEdgeLength(
            integrands.facetGeometry())
        predefined[minFacetEdgeLength] = minEdgeLength(
            integrands.facetGeometry())
        integrands.predefineCoefficients(predefined, False)
        integrands.boundary = generateUnaryCode(predefined,
                                                derivatives_phi,
                                                integrals['exterior_facet'],
                                                tempVars=tempVars)

        predefined = {
            derivatives_ubar[i]: arg[i]
            for i in range(len(derivatives_u))
        }
        predefined[x] = integrands.spatialCoordinate('x')
        predefined[n] = integrands.facetNormal('x')
        predefined[cellVolume] = integrands.cellVolume()
        predefined[maxCellEdgeLength] = maxEdgeLength(
            integrands.cellGeometry())
        predefined[minCellEdgeLength] = minEdgeLength(
            integrands.cellGeometry())
        predefined[facetArea] = integrands.facetArea()
        predefined[maxFacetEdgeLength] = maxEdgeLength(
            integrands.facetGeometry())
        predefined[minFacetEdgeLength] = minEdgeLength(
            integrands.facetGeometry())
        integrands.predefineCoefficients(predefined, False)
        integrands.linearizedBoundary = generateUnaryLinearizedCode(
            predefined,
            derivatives_phi,
            derivatives_u,
            linearizedIntegrals.get('exterior_facet'),
            tempVars=tempVars)

    if 'interior_facet' in integrals.keys():
        argIn = Variable(integrands.domainValueTuple, 'uIn')
        argOut = Variable(integrands.domainValueTuple, 'uOut')

        predefined = {
            derivatives_u[i](s): arg[i]
            for i in range(len(derivatives_u))
            for s, arg in (('+', argIn), ('-', argOut))
        }
        predefined[x] = integrands.spatialCoordinate('xIn')
        predefined[n('+')] = integrands.facetNormal('xIn')
        predefined[cellVolume('+')] = integrands.cellVolume('Side::in')
        predefined[cellVolume('-')] = integrands.cellVolume('Side::out')
        predefined[maxCellEdgeLength('+')] = maxEdgeLength(
            integrands.cellGeometry('Side::in'))
        predefined[maxCellEdgeLength('-')] = maxEdgeLength(
            integrands.cellGeometry('Side::out'))
        predefined[minCellEdgeLength('+')] = minEdgeLength(
            integrands.cellGeometry('Side::in'))
        predefined[minCellEdgeLength('-')] = minEdgeLength(
            integrands.cellGeometry('Side::out'))
        predefined[facetArea] = integrands.facetArea()
        predefined[maxFacetEdgeLength] = maxEdgeLength(
            integrands.facetGeometry())
        predefined[minFacetEdgeLength] = minEdgeLength(
            integrands.facetGeometry())
        integrands.predefineCoefficients(predefined, True)
        integrands.skeleton = generateBinaryCode(predefined,
                                                 derivatives_phi,
                                                 integrals['interior_facet'],
                                                 tempVars=tempVars)

        predefined = {
            derivatives_ubar[i](s): arg[i]
            for i in range(len(derivatives_u))
            for s, arg in (('+', argIn), ('-', argOut))
        }
        predefined[x] = integrands.spatialCoordinate('xIn')
        predefined[n('+')] = integrands.facetNormal('xIn')
        predefined[cellVolume('+')] = integrands.cellVolume('Side::in')
        predefined[cellVolume('-')] = integrands.cellVolume('Side::out')
        predefined[maxCellEdgeLength('+')] = maxEdgeLength(
            integrands.cellGeometry('Side::in'))
        predefined[maxCellEdgeLength('-')] = maxEdgeLength(
            integrands.cellGeometry('Side::out'))
        predefined[minCellEdgeLength('+')] = minEdgeLength(
            integrands.cellGeometry('Side::in'))
        predefined[minCellEdgeLength('-')] = minEdgeLength(
            integrands.cellGeometry('Side::out'))
        predefined[facetArea] = integrands.facetArea()
        predefined[maxFacetEdgeLength] = maxEdgeLength(
            integrands.facetGeometry())
        predefined[minFacetEdgeLength] = minEdgeLength(
            integrands.facetGeometry())
        integrands.predefineCoefficients(predefined, True)
        integrands.linearizedSkeleton = generateBinaryLinearizedCode(
            predefined,
            derivatives_phi,
            derivatives_u,
            linearizedIntegrals.get('interior_facet'),
            tempVars=tempVars)

    if dirichletBCs:
        integrands.hasDirichletBoundary = True

        predefined = {}
        # predefined[x] = UnformattedExpression('auto', 'entity().geometry().global( Dune::Fem::coordinate( ' + integrands.arg_x.name + ' ) )')
        predefined[x] = UnformattedExpression(
            'auto', 'intersection.geometry().center( )')
        integrands.predefineCoefficients(predefined, False)

        maxId = 0
        codeDomains = []
        bySubDomain = dict()
        neuman = []
        wholeDomain = None
        for bc in dirichletBCs:
            if bc.subDomain in bySubDomain:
                raise Exception(
                    'Multiply defined Dirichlet boundary for subdomain ' +
                    str(bc.subDomain))
            if not isinstance(bc.functionSpace,
                              (FunctionSpace, FiniteElementBase)):
                raise Exception(
                    'Function space must either be a ufl.FunctionSpace or a ufl.FiniteElement'
                )
            if isinstance(bc.functionSpace, FunctionSpace) and (
                    bc.functionSpace != u.ufl_function_space()):
                raise Exception(
                    'Space of trial function and dirichlet boundary function must be the same - note that boundary conditions on subspaces are not available, yet'
                )
            if isinstance(bc.functionSpace, FiniteElementBase) and (
                    bc.functionSpace != u.ufl_element()):
                raise Exception(
                    'Cannot handle boundary conditions on subspaces, yet')

            if isinstance(bc.value, list):
                neuman = [i for i, x in enumerate(bc.value) if x == None]
            else:
                neuman = []

            value = ExprTensor(u.ufl_shape)
            for key in value.keys():
                value[key] = Indexed(
                    bc.ufl_value,
                    MultiIndex(tuple(FixedIndex(k) for k in key)))
            if bc.subDomain is None:
                wholeDomain = value, neuman
            elif isinstance(bc.subDomain, int):
                bySubDomain[bc.subDomain] = value, neuman
                maxId = max(maxId, bc.subDomain)
            else:
                domain = ExprTensor(())
                for key in domain.keys():
                    domain[key] = Indexed(
                        bc.subDomain,
                        MultiIndex(tuple(FixedIndex(k) for k in key)))
                codeDomains.append((value, neuman, domain))
        defaultCode = []
        if len(codeDomains) > 0:
            defaultCode.append(Declaration(Variable('int', 'domainId')))
        # defaultCode.append(Declaration(Variable('auto', 'x'),
        #     initializer=UnformattedExpression('auto','intersection.geometry().center()')))
        for i, v in enumerate(codeDomains):
            block = Block()
            block.append(
                generateDirichletDomainCode(predefined,
                                            v[2],
                                            tempVars=tempVars))
            block.append('if (domainId)')
            ifBlock = UnformattedBlock()
            ifBlock.append(
                'std::fill( dirichletComponent.begin(), dirichletComponent.end(), '
                + str(maxId + i + 2) + ' );')
            if len(v[1]) > 0:
                [
                    ifBlock.append('dirichletComponent[' + str(c) + '] = 0;')
                    for c in v[1]
                ]
            ifBlock.append('return true;')
            block.append(ifBlock)
            defaultCode.append(block)
        if wholeDomain is not None:
            block = UnformattedBlock()
            block.append(
                'std::fill( dirichletComponent.begin(), dirichletComponent.end(), '
                + str(maxId + 1) + ' );')
            if len(wholeDomain[1]) > 0:
                [
                    block.append('dirichletComponent[' + str(c) + '] = 0;')
                    for c in wholeDomain[1]
                ]
            block.append('return true;')
            defaultCode.append(block)
        defaultCode.append(return_(False))

        bndId = Variable('const int', 'bndId')
        getBndId = UnformattedExpression(
            'int', 'BoundaryIdProviderType::boundaryId( ' +
            integrands.arg_i.name + ' )')
        # getBndId = UnformattedExpression('int', 'boundaryIdGetter_.boundaryId( ' + integrands.arg_i.name + ' )')
        switch = SwitchStatement(bndId, default=defaultCode)
        for i, v in bySubDomain.items():
            code = []
            if len(v[1]) > 0:
                [
                    code.append('dirichletComponent[' + str(c) + '] = 0;')
                    for c in v[1]
                ]
            code.append(return_(True))
            switch.append(i, code)
        integrands.isDirichletIntersection = [
            Declaration(bndId, initializer=getBndId),
            UnformattedBlock(
                'std::fill( dirichletComponent.begin(), dirichletComponent.end(), '
                + bndId.name + ' );'), switch
        ]

        predefined[x] = UnformattedExpression(
            'auto', 'entity().geometry().global( Dune::Fem::coordinate( ' +
            integrands.arg_x.name + ' ) )')
        if wholeDomain is None:
            defaultCode = assign(integrands.arg_r, construct("RRangeType", 0))
        else:
            defaultCode = generateDirichletCode(predefined,
                                                wholeDomain[0],
                                                tempVars=tempVars)
        switch = SwitchStatement(integrands.arg_bndId, default=defaultCode)
        for i, v in bySubDomain.items():
            switch.append(
                i, generateDirichletCode(predefined, v[0], tempVars=tempVars))
        for i, v in enumerate(codeDomains):
            switch.append(
                i + maxId + 2,
                generateDirichletCode(predefined, v[0], tempVars=tempVars))
        integrands.dirichlet = [switch]

    return integrands
Ejemplo n.º 18
0
    def __init__(self, args, tc, metadata):
        self.has_analytic_solution = True
        self.problem_code = 'SCYL'
        super(Problem, self).__init__(args, tc, metadata)

        self.tc.init_watch('errorP', 'Computed pressure error', True)
        self.tc.init_watch('errorV', 'Computed velocity error', True)
        self.tc.init_watch('errorForce', 'Computed force error', True)
        self.tc.init_watch('errorVtest', 'Computed velocity error test', True)
        self.tc.init_watch('computePG', 'Computed pressure gradient', True)

        self.name = 'steady_cylinder'
        self.status_functional_str = 'last H1 velocity error'

        # input parameters
        self.ic = args.ic
        self.factor = args.factor
        self.metadata['factor'] = self.factor
        self.scale_factor.append(self.factor)

        # fixed parameters (used in analytic solution and in BC)
        self.nu = 3.71  # kinematic viscosity
        self.R = 5.0  # cylinder radius

        self.mesh_volume = pi * 25. * 20.

        # Import gmsh mesh
        self.tc.start('mesh')
        self.mesh, self.facet_function = super(Problem,
                                               self).loadMesh(args.mesh)
        self.dsIn = Measure("ds",
                            subdomain_id=2,
                            subdomain_data=self.facet_function)
        self.dsOut = Measure("ds",
                             subdomain_id=3,
                             subdomain_data=self.facet_function)
        self.dsWall = Measure("ds",
                              subdomain_id=1,
                              subdomain_data=self.facet_function)
        self.normal = FacetNormal(self.mesh)
        print("Mesh name: ", args.mesh, "    ", self.mesh)
        print("Mesh norm max: ", self.mesh.hmax())
        print("Mesh norm min: ", self.mesh.hmin())
        self.tc.end('mesh')

        self.sol_p = None
        self.analytic_gradient = None
        self.analytic_pressure_norm = None
        self.v_in = None
        self.area = None

        self.analytic_v_norm_L2 = None
        self.analytic_v_norm_H1 = None
        self.analytic_v_norm_H1w = None

        self.listDict.update({
            'u_H1w': {
                'list': [],
                'name': 'corrected velocity H1 error on wall',
                'abrev': 'CE_H1w',
                'scale': self.scale_factor,
                'relative': 'av_norm_H1w',
                'slist': []
            },
            'u2H1w': {
                'list': [],
                'name': 'tentative velocity H1 error on wall',
                'abrev': 'TE_H1w',
                'scale': self.scale_factor,
                'relative': 'av_norm_H1w',
                'slist': []
            },
            'av_norm_H1w': {
                'list': [],
                'name': 'analytic velocity H1 norm on wall',
                'abrev': 'AVN_H1w'
            },
            'a_force_wall': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AF'
            },
            'a_force_wall_normal': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AFN'
            },
            'a_force_wall_shear': {
                'list': [],
                'name': 'analytic force on wall',
                'abrev': 'AFS'
            },
            'force_wall': {
                'list': [],
                'name': 'force error on wall',
                'abrev': 'FE',
                'relative': 'a_force_wall',
                'slist': []
            },
            'force_wall_normal': {
                'list': [],
                'name': 'normal force error on wall',
                'abrev': 'FNE',
                'relative': 'a_force_wall',
                'slist': []
            },
            'force_wall_shear': {
                'list': [],
                'name': 'shear force error on wall',
                'abrev': 'FSE',
                'relative': 'a_force_wall',
                'slist': []
            },
        })
Ejemplo n.º 19
0
    def readin_mesh(self):

        if self.meshfile_type=='ASCII':
            encoding = XDMFFile.Encoding.ASCII
        elif self.meshfile_type=='HDF5':
            encoding = XDMFFile.Encoding.HDF5
        else:
            raise NameError('Choose either ASCII or HDF5 as meshfile_type, or add a different encoding!')
            
        # read in xdmf mesh - domain
        with XDMFFile(self.comm, self.mesh_domain, 'r', encoding=encoding) as infile:
            self.mesh = infile.read_mesh(name="Grid")
            self.mt_d = infile.read_meshtags(self.mesh, name="Grid")
        
        # read in xdmf mesh - boundary
        
        # here, we define b1 BCs as BCs associated to a topology one dimension less than the problem (most common),
        # b2 BCs two dimensions less, and b3 BCs three dimensions less
        # for a 3D problem - b1: surface BCs, b2: edge BCs, b3: point BCs
        # for a 2D problem - b1: edge BCs, b2: point BCs
        # 1D problems not supported (currently...)
        
        if self.mesh.topology.dim == 3:
            
            try:
                self.mesh.topology.create_connectivity(2, self.mesh.topology.dim)
                with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile:
                    self.mt_b1 = infile.read_meshtags(self.mesh, name="Grid")
            except:
                pass
            
            try:
                self.mesh.topology.create_connectivity(1, self.mesh.topology.dim)
                with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile:
                    self.mt_b2 = infile.read_meshtags(self.mesh, name="Grid_b2")
            except:
                pass

            try:
                self.mesh.topology.create_connectivity(0, self.mesh.topology.dim)
                with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile:
                    self.mt_b3 = infile.read_meshtags(self.mesh, name="Grid_b3")
            except:
                pass

        elif self.mesh.topology.dim == 2:
            
            try:
                self.mesh.topology.create_connectivity(1, self.mesh.topology.dim)
                with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile:
                    self.mt_b1 = infile.read_meshtags(self.mesh, name="Grid")
            except:
                pass
            
            try:
                self.mesh.topology.create_connectivity(0, self.mesh.topology.dim)
                with XDMFFile(self.comm, self.mesh_boundary, 'r', encoding=encoding) as infile:
                    self.mt_b2 = infile.read_meshtags(self.mesh, name="Grid_b2")
            except:
                pass

        else:
            raise AttributeError("Your mesh seems to be 1D! Not supported!")

        # useful fields:
        
        # facet normal
        self.n0 = FacetNormal(self.mesh)
        # cell diameter
        self.h0 = CellDiameter(self.mesh)