Пример #1
0
def Q(mesh):
    W = VectorElement('CG', mesh.ufl_cell(), 1)
    V = FiniteElement('CG', mesh.ufl_cell(), 1)
    return FunctionSpace(mesh, W * V)
Пример #2
0
    def __init__(self, nxs, bcs, name='singleblockmesh', coordelem=None):
        assert (len(nxs) == len(bcs))

        self.ndim = len(nxs)

        self.nxs = [
            nxs,
        ]
        self.bcs = bcs
        self.npatches = 1
        self.patchlist = []
        self._name = name
        self._blist = []

        for bc in bcs:
            if bc == 'periodic':
                self._blist.append(PETSc.DM.BoundaryType.PERIODIC)
            else:
                self._blist.append(PETSc.DM.BoundaryType.GHOSTED)

        bdx = 0
        bdy = 0
        bdz = 0
        edgex_nxs = list(nxs)
        if (bcs[0] == 'nonperiodic'):
            edgex_nxs[0] = edgex_nxs[0] + 1
            bdx = 1
        if self.ndim >= 2:
            edgey_nxs = list(nxs)
            if (bcs[1] == 'nonperiodic'):
                edgey_nxs[1] = edgey_nxs[1] + 1
                bdy = 1

        if self.ndim >= 3:
            edgez_nxs = list(nxs)
            if (bcs[2] == 'nonperiodic'):
                edgez_nxs[2] = edgez_nxs[2] + 1
                bdz = 1

        # generate mesh
        cell_da = PETSc.DMDA().create()
        #THIS SHOULD REALLY BE AN OPTIONS PREFIX THING TO MESH...
        #MAIN THING IS THE ABILITY TO CONTROL DECOMPOSITION AT COMMAND LINE
        #BUT WE WANT TO BE ABLE TO IGNORE DECOMPOSITION WHEN RUNNING WITH A SINGLE PROCESSOR
        #WHICH ALLOWS THE SAME OPTIONS LIST TO BE USED TO RUN SOMETHING IN PARALLEL, AND THEN DO PLOTTING IN SERIAL!
        if PETSc.COMM_WORLD.size > 1:  #this allows the same options list to be used to run something in parallel, but then plot it in serial!
            cell_da.setOptionsPrefix(self._name + '0_')
            cell_da.setFromOptions()
        #############

        cell_da.setDim(self.ndim)
        cell_da.setDof(1)
        cell_da.setSizes(nxs)
        cell_da.setBoundaryType(self._blist)
        cell_da.setStencil(PETSc.DMDA.StencilType.BOX, 1)
        cell_da.setUp()

        #print self.cell_da.getProcSizes()
        edgex_da = PETSc.DMDA().create(dim=self.ndim,
                                       dof=1,
                                       sizes=edgex_nxs,
                                       proc_sizes=cell_da.getProcSizes(),
                                       boundary_type=self._blist,
                                       stencil_type=PETSc.DMDA.StencilType.BOX,
                                       stencil_width=1,
                                       setup=False)
        #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN
        decompfunction(cell_da, edgex_da, self.ndim, 1, 1, 1, bdx, 0, 0)
        edgex_da.setUp()

        if self.ndim >= 2:
            edgey_da = PETSc.DMDA().create(
                dim=self.ndim,
                dof=1,
                sizes=edgey_nxs,
                proc_sizes=cell_da.getProcSizes(),
                boundary_type=self._blist,
                stencil_type=PETSc.DMDA.StencilType.BOX,
                stencil_width=1,
                setup=False)
            #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN
            decompfunction(cell_da, edgey_da, self.ndim, 1, 1, 1, 0, bdy, 0)
            edgey_da.setUp()
        if self.ndim >= 3:
            edgez_da = PETSc.DMDA().create(
                dim=self.ndim,
                dof=1,
                sizes=edgez_nxs,
                proc_sizes=cell_da.getProcSizes(),
                boundary_type=self._blist,
                stencil_type=PETSc.DMDA.StencilType.BOX,
                stencil_width=1,
                setup=False)
            #THIS IS AN UGLY HACK NEEDED BECAUSE OWNERSHIP RANGES ARGUMENT TO petc4py DMDA_CREATE is BROKEN
            decompfunction(cell_da, edgez_da, self.ndim, 1, 1, 1, 0, 0, bdz)
            edgez_da.setUp()

        self._cell_das = [
            cell_da,
        ]
        self._edgex_das = [
            edgex_da,
        ]
        self._edgex_nxs = [
            edgex_nxs,
        ]
        if self.ndim >= 2:
            self._edgey_das = [
                edgey_da,
            ]
            self._edgey_nxs = [
                edgey_nxs,
            ]
        if self.ndim >= 3:
            self._edgez_das = [
                edgez_da,
            ]
            self._edgez_nxs = [
                edgez_nxs,
            ]

        #ADD ACTUAL COORDINATE FUNCTION INITIALIZATION HERE

        #construct coordelem
        #FIX THIS- SHOULD USE H1 FOR NON-PERIODIC!
        #Use DG for periodic boundaries to avoid wrapping issues
        h1elem = FiniteElement("CG", interval, 1)  #1 dof per element = linear
        l2elem = FiniteElement("DG", interval, 1)  #2 dofs per element = linear
        elemlist = []
        dxs = []
        pxs = []
        lxs = []
        for i in range(len(nxs)):
            dxs.append(2.)
            pxs.append(0.)
            lxs.append(2. * nxs[i])
            #if bcs[i] == 'periodic':
            elemlist.append(l2elem)
            #else:
            #	elemlist.append(h1elem)
        celem = TensorProductElement(*elemlist)
        if len(nxs) == 1:
            celem = elemlist[0]
        if not (coordelem == None):
            celem = coordelem
        celem = VectorElement(celem, dim=self.ndim)

        Mesh.__init__(self, celem)

        #THIS BREAKS FOR COORDELEM NOT DG1...
        #construct and set coordsvec
        coordsspace = FunctionSpace(self, celem)
        self.coordinates = Function(coordsspace, name='coords')

        localnxs = self.get_local_nxny(0)
        newcoords = create_uniform_nodal_coords(self.get_cell_da(0), nxs, pxs,
                                                lxs, dxs, bcs, localnxs)

        coordsdm = coordsspace.get_da(0, 0)
        coordsarr = coordsdm.getVecArray(self.coordinates._vector)[:]

        if len(pxs) == 1:
            coordsarr[:] = np.squeeze(newcoords[:])
        else:
            coordsarr[:] = newcoords[:]

        self.coordinates.scatter()
Пример #3
0
xdmf = XDMFFile(MPI.comm_world, "../dolfin_fine.xdmf")
mesh = xdmf.read_mesh(dolfin.cpp.mesh.GhostMode.none)

sub_domains = xdmf.read_mf_size_t(mesh)

cmap = dolfin.fem.create_coordinate_map(mesh.ufl_domain())
mesh.geometry.coord_mapping = cmap

# Next, we define a :py:class:`FunctionSpace
# <dolfin.functions.functionspace.FunctionSpace>` built on a mixed
# finite element ``TH`` which consists of continuous
# piecewise quadratics and continuous piecewise
# linears::

# Define function spaces
P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)

# The mixed finite element space is known as Taylor–Hood.
# It is a stable, standard element pair for the Stokes
# equations. Now we can define boundary conditions::

# No-slip boundary condition for velocity
# x1 = 0, x1 = 1 and around the dolphin


class NoSlip:
    """Evaluate the no-slip condition"""
Пример #4
0
def test_save_and_checkpoint_vector(tempdir, encoding, fe_degree, fe_family,
                                    mesh_tdim, mesh_n):
    if invalid_fe(fe_family, fe_degree):
        pytest.skip("Trivial finite element")

    filename = os.path.join(tempdir, "u2_checkpoint.xdmf")
    mesh = mesh_factory(mesh_tdim, mesh_n)
    FE = VectorElement(fe_family, mesh.ufl_cell(), fe_degree)
    V = FunctionSpace(mesh, FE)
    u_in = Function(V)
    u_out = Function(V)

    if has_petsc_complex:
        if mesh.geometry.dim == 1:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = x[:, 0] + 1.0j * x[:, 0]
            u_out.interpolate(Expression(expr_eval, shape=(1,)))

        elif mesh.geometry.dim == 2:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = 1.0j * x[:, 0] * x[:, 1]
                values[:, 1] = x[:, 0] + 1.0j * x[:, 0]
            u_out.interpolate(Expression(expr_eval, shape=(2,)))

        elif mesh.geometry.dim == 3:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = x[:, 0] * x[:, 1]
                values[:, 1] = x[:, 0] + 1.0j * x[:, 0]
                values[:, 2] = x[:, 2]
            u_out.interpolate(Expression(expr_eval, shape=(3,)))
    else:
        if mesh.geometry.dim == 1:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = x[:, 0]
            u_out.interpolate(Expression(expr_eval, shape=(1,)))

        elif mesh.geometry.dim == 2:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = x[:, 0] * x[:, 1]
                values[:, 1] = x[:, 0]
            u_out.interpolate(Expression(expr_eval, shape=(2,)))

        elif mesh.geometry.dim == 3:
            @function.expression.numba_eval
            def expr_eval(values, x, cell_idx):
                values[:, 0] = x[:, 0] * x[:, 1]
                values[:, 1] = x[:, 0]
                values[:, 2] = x[:, 2]
            u_out.interpolate(Expression(expr_eval, shape=(3,)))

    with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file:
        file.write_checkpoint(u_out, "u_out", 0)

    with XDMFFile(mesh.mpi_comm(), filename) as file:
        u_in = file.read_checkpoint(V, "u_out", 0)

    u_in.vector().axpy(-1.0, u_out.vector())
    assert u_in.vector().norm() < 1.0e-12
Пример #5
0
def mass_cg(cell, degree):
    m = Mesh(VectorElement('Q', cell, 1))
    V = FunctionSpace(m, FiniteElement('Q', cell, degree, variant='spectral'))
    u = TrialFunction(V)
    v = TestFunction(V)
    return u * v * dx(rule=gll_quadrature_rule(cell, degree))
Пример #6
0
def laplace(cell, degree):
    m = Mesh(VectorElement('Q', cell, 1))
    V = FunctionSpace(m, FiniteElement('Q', cell, degree, variant='spectral'))
    u = TrialFunction(V)
    v = TestFunction(V)
    return dot(grad(u), grad(v)) * dx(rule=gll_quadrature_rule(cell, degree))
def V(mesh):
    return FunctionSpace(mesh, VectorElement("DP", triangle, 1))
Пример #8
0
#
# Harmonic map demo using one mixed function u to represent x and y.
# Author: Martin Alnes
# Date: 2009-04-09
#
from ufl import (Coefficient, FiniteElement, VectorElement, derivative, dot,
                 dx, grad, inner, split, triangle)

cell = triangle
X = VectorElement("Lagrange", cell, 1)
Y = FiniteElement("Lagrange", cell, 1)
M = X * Y

u = Coefficient(M)
x, y = split(u)

L = inner(grad(x), grad(x)) * dx + dot(x, x) * y * dx

F = derivative(L, u)
J = derivative(F, u)

forms = [L, F, J]
def mesh():
    return Mesh(VectorElement("P", triangle, 1))
Пример #10
0
from ufl import (MixedElement, TestFunctions, TrialFunctions, VectorElement,
                 as_vector, div, dot, dx, inner, skew, tetrahedron, tr)


def skw(tau):
    """Define vectorized skew operator"""
    sk = 2 * skew(tau)
    return as_vector((sk[0, 1], sk[0, 2], sk[1, 2]))


cell = tetrahedron
n = 3

# Finite element exterior calculus syntax
r = 1
S = VectorElement("P Lambda", cell, r, form_degree=n - 1)
V = VectorElement("P Lambda", cell, r - 1, form_degree=n)
Q = VectorElement("P Lambda", cell, r - 1, form_degree=n)

# Alternative syntax:
# S = VectorElement("BDM", cell, r)
# V = VectorElement("Discontinuous Lagrange", cell, r-1)
# Q = VectorElement("Discontinuous Lagrange", cell, r-1)

W = MixedElement(S, V, Q)

(sigma, u, gamma) = TrialFunctions(W)
(tau, v, eta) = TestFunctions(W)

a = (inner(sigma, tau) - tr(sigma) * tr(tau) +
     dot(div(tau), u) - dot(div(sigma), v) +
Пример #11
0
#
# Author: Martin Sandve Alnes
# Date: 2008-10-03
#
from ufl import (Coefficient, TestFunction, TrialFunction, VectorElement, dx,
                 i, j, triangle)

element = VectorElement("Lagrange", triangle, 1)

u = TrialFunction(element)
v = TestFunction(element)
w = Coefficient(element)

a = (u[j] * w[i].dx(j) + w[j] * u[i].dx(j)) * v[i] * dx
Пример #12
0
#

# Modified by Garth N. Wells, 2009
from ufl import (Coefficient, Constant, FacetNormal, FiniteElement, Identity,
                 SpatialCoordinate, TensorElement, TestFunction, TrialFunction,
                 VectorElement, derivative, det, diff, dot, ds, dx, exp, grad,
                 inner, inv, tetrahedron, tr, variable)

# Cell and its properties
cell = tetrahedron
d = cell.geometric_dimension()
N = FacetNormal(cell)
x = SpatialCoordinate(cell)

# Elements
u_element = VectorElement("CG", cell, 2)
p_element = FiniteElement("CG", cell, 1)
A_element = TensorElement("CG", cell, 1)

# Test and trial functions
v = TestFunction(u_element)
w = TrialFunction(u_element)

# Displacement at current and two previous timesteps
u = Coefficient(u_element)
up = Coefficient(u_element)
upp = Coefficient(u_element)

# Time parameters
dt = Constant(cell)
Пример #13
0
    def __init__(self,
                 io_params,
                 time_params,
                 fem_params,
                 constitutive_models,
                 bc_dict,
                 time_curves,
                 io,
                 comm=None):
        problem_base.__init__(self, io_params, time_params, comm)

        self.problem_physics = 'fluid'

        self.simname = io_params['simname']

        self.io = io

        # number of distinct domains (each one has to be assigned a own material model)
        self.num_domains = len(constitutive_models)

        self.order_vel = fem_params['order_vel']
        self.order_pres = fem_params['order_pres']
        self.quad_degree = fem_params['quad_degree']

        # collect domain data
        self.dx_, self.rho = [], []
        for n in range(self.num_domains):
            # integration domains
            self.dx_.append(
                dx(subdomain_data=self.io.mt_d,
                   subdomain_id=n + 1,
                   metadata={'quadrature_degree': self.quad_degree}))
            # data for inertial forces: density
            self.rho.append(constitutive_models['MAT' + str(n + 1) +
                                                '']['inertia']['rho'])

        self.incompressible_2field = True  # always true!
        self.localsolve = False  # no idea what might have to be solved locally...
        self.prestress_initial = False  # guess prestressing in fluid is somehow senseless...
        self.p11 = as_ufl(
            0
        )  # can't think of a fluid case with non-zero 11-block in system matrix...

        # type of discontinuous function spaces
        if str(self.io.mesh.ufl_cell()) == 'tetrahedron' or str(
                self.io.mesh.ufl_cell()) == 'triangle3D':
            dg_type = "DG"
            if (self.order_vel > 1
                    or self.order_pres > 1) and self.quad_degree < 3:
                raise ValueError(
                    "Use at least a quadrature degree of 3 or more for higher-order meshes!"
                )
        elif str(self.io.mesh.ufl_cell()) == 'hexahedron' or str(
                self.io.mesh.ufl_cell()) == 'quadrilateral3D':
            dg_type = "DQ"
            if (self.order_vel > 1
                    or self.order_pres > 1) and self.quad_degree < 4:
                raise ValueError(
                    "Use at least a quadrature degree of 4 or more for higher-order meshes!"
                )
        else:
            raise NameError("Unknown cell/element type!")

        # create finite element objects for v and p
        self.P_v = VectorElement("CG", self.io.mesh.ufl_cell(), self.order_vel)
        self.P_p = FiniteElement("CG", self.io.mesh.ufl_cell(),
                                 self.order_pres)
        # function spaces for v and p
        self.V_v = FunctionSpace(self.io.mesh, self.P_v)
        self.V_p = FunctionSpace(self.io.mesh, self.P_p)

        # a discontinuous tensor, vector, and scalar function space
        self.Vd_tensor = TensorFunctionSpace(self.io.mesh,
                                             (dg_type, self.order_vel - 1))
        self.Vd_vector = VectorFunctionSpace(self.io.mesh,
                                             (dg_type, self.order_vel - 1))
        self.Vd_scalar = FunctionSpace(self.io.mesh,
                                       (dg_type, self.order_vel - 1))

        # functions
        self.dv = TrialFunction(self.V_v)  # Incremental velocity
        self.var_v = TestFunction(self.V_v)  # Test function
        self.dp = TrialFunction(self.V_p)  # Incremental pressure
        self.var_p = TestFunction(self.V_p)  # Test function
        self.v = Function(self.V_v, name="Velocity")
        self.p = Function(self.V_p, name="Pressure")
        # values of previous time step
        self.v_old = Function(self.V_v)
        self.a_old = Function(self.V_v)
        self.p_old = Function(self.V_p)

        self.ndof = self.v.vector.getSize() + self.p.vector.getSize()

        # initialize fluid time-integration class
        self.ti = timeintegration.timeintegration_fluid(
            time_params, fem_params, time_curves, self.t_init, self.comm)

        # initialize kinematics_constitutive class
        self.ki = fluid_kinematics_constitutive.kinematics()

        # initialize material/constitutive class
        self.ma = []
        for n in range(self.num_domains):
            self.ma.append(
                fluid_kinematics_constitutive.constitutive(
                    self.ki, constitutive_models['MAT' + str(n + 1) + '']))

        # initialize fluid variational form class
        self.vf = fluid_variationalform.variationalform(
            self.var_v, self.dv, self.var_p, self.dp, self.io.n0)

        # initialize boundary condition class
        self.bc = boundaryconditions.boundary_cond_fluid(
            bc_dict, fem_params, self.io, self.ki, self.vf, self.ti)

        self.bc_dict = bc_dict

        # Dirichlet boundary conditions
        if 'dirichlet' in self.bc_dict.keys():
            self.bc.dirichlet_bcs(self.V_v)

        self.set_variational_forms_and_jacobians()