def __init__(self, mesh, lame, model):
        def sigmaLaw(u):
            return lame[0] * nabla_div(u) * df.Identity(
                2) + 2 * lame[1] * symgrad(u)

        self.sigmaLaw = sigmaLaw

        self.mesh = mesh
        self.model = model
        self.coord_min = np.min(self.mesh.coordinates(), axis=0)
        self.coord_max = np.max(self.mesh.coordinates(), axis=0)

        # it should be modified before computing tangent (if needed)
        self.others = {
            'polyorder': 1,
            'x0': self.coord_min[0],
            'x1': self.coord_max[0],
            'y0': self.coord_min[1],
            'y1': self.coord_max[1]
        }

        self.multiscaleModel = listMultiscaleModels[model]
        self.x = df.SpatialCoordinate(self.mesh)
        self.ndim = 2
        self.nvoigt = int(self.ndim * (self.ndim + 1) / 2)
        self.Chom_ = np.zeros((self.nvoigt, self.nvoigt))

        # in the first run should compute
        self.getTangent = self.computeTangent
Ejemplo n.º 2
0
def _CenterVector(mesh, Center):
    '''DLT vector pointing on each facet from one Center to the other'''
    # Cell-cell distance for the interior facet is defined as a distance
    # of circumcenters. For exterior it is facet centor to circumcenter
    # For facet centers we use DLT projection
    if mesh.topology().dim() > 1:
        L = df.VectorFunctionSpace(mesh, 'Discontinuous Lagrange Trace', 0)
    else:
        L = df.VectorFunctionSpace(mesh, 'CG', 1)

    fK = df.FacetArea(mesh)
    l = df.TestFunction(L)

    x = df.SpatialCoordinate(mesh)
    facet_centers = df.Function(L)
    df.assemble((1 / fK) * df.inner(x, l) * df.ds,
                tensor=facet_centers.vector())

    cell_centers = Center(mesh)

    cc = df.Function(L)
    # Finally we assemble magniture of the vector that is determined by the
    # two centers
    df.assemble(
        (1 / fK('+')) *
        df.inner(cell_centers('+') - cell_centers('-'), l('+')) * df.dS +
        (1 / fK) * df.inner(cell_centers - facet_centers, l) * df.ds,
        tensor=cc.vector())

    return cc
Ejemplo n.º 3
0
def get_volume(geometry, u=None, chamber="lv"):

    if "ENDO" in geometry.markers:
        lv_endo_marker = geometry.markers["ENDO"]
        rv_endo_marker = None
    else:
        lv_endo_marker = geometry.markers["ENDO_LV"]
        rv_endo_marker = geometry.markers["ENDO_RV"]

    marker = lv_endo_marker if chamber == "lv" else rv_endo_marker

    if marker is None:
        return None

    if hasattr(marker, "__len__"):
        marker = marker[0]

    ds = df.Measure(
        "exterior_facet", subdomain_data=geometry.ffun, domain=geometry.mesh
    )(marker)

    X = df.SpatialCoordinate(geometry.mesh)
    N = df.FacetNormal(geometry.mesh)

    if u is None:
        vol = df.assemble((-1.0 / 3.0) * df.dot(X, N) * ds)
    else:
        F = df.grad(u) + df.Identity(3)
        J = df.det(F)
        vol = df.assemble((-1.0 / 3.0) * df.dot(X + u, J * df.inv(F).T * N) * ds)

    return vol
Ejemplo n.º 4
0
 def setUp(self):
     self.mesh = mesh = dolfin.UnitIntervalMesh(30)
     self.element = element = dolfin.FiniteElement("CG", mesh.ufl_cell(), 3)
     self.W = W = dolfin.FunctionSpace(mesh, element)
     self.u = dolfin.Function(W, name='u')
     self.v = dolfin.TestFunction(W)
     self.x = dolfin.SpatialCoordinate(mesh)[0]
    def __init__(self, Vh, nu, ds_ff, u_ff, inletMomentun, inletWidth):
        """
        Contructor
        
        INPUTS:
        - Vh: the mixed finite element space for the state variable
        - nu: the kinetic viscosity
        - ds_ff: the integrator on the farfield boundary (where we impose the swithcing Dir/Neu conditions
        - u_ff: the farfield Dirichlet condition for the normal component of the velocity field u (when backflow is detected)
        - inletMomentun, inletWidth: the standard parameters in the algebraic closure model
        """
        self.Vh = Vh
        self.mesh = Vh.mesh()
        self.nu = nu

        self.ds_ff = ds_ff
        self.u_ff = u_ff

        self.inletMomentun = inletMomentun
        self.inletWidth = inletWidth

        self.metric = mesh_metric(self.mesh)
        self.n = dl.FacetNormal(self.mesh)
        self.tg = dl.perp(self.n)

        self.reg_norm = dl.Constant(1e-1)
        self.Cd = dl.Constant(1e5)

        #self.xfun = dl.Expression("x[0]", element = self.Vh.sub(1).ufl_element())
        self.xfun, self.yfun = dl.SpatialCoordinate(self.mesh)
Ejemplo n.º 6
0
    def setUp(self):
        from dolfin import (MixedElement as MixE, Function, FunctionSpace,
                            FiniteElement, VectorElement, UnitSquareMesh)
        self.mesh = mesh = UnitSquareMesh(10, 10)
        muc = mesh.ufl_cell

        self.fe1 = FiniteElement("CG", muc(), 1)
        self.fe2 = FiniteElement("CG", muc(), 2)
        self.ve1 = VectorElement("CG", muc(), 2, 2)

        self.me = (
            MixE([self.fe1, self.fe2]),
            MixE([MixE([self.ve1, self.fe2]), self.fe1, self.ve1, self.fe2]),
            # MixE([self.fe1]), # broken
        )

        self.W = [FunctionSpace(mesh, me) for me in self.me]

        self.w = [Function(W) for W in self.W]

        self.reg = FunctionSubspaceRegistry()

        self.x = dolfin.SpatialCoordinate(mesh)

        for W in self.W:
            self.reg.register(W)
Ejemplo n.º 7
0
def main():
    fsr = FunctionSubspaceRegistry()

    deg = 2
    mesh = dolfin.UnitSquareMesh(100, 3)
    muc = mesh.ufl_cell()
    el_w = dolfin.FiniteElement('DG', muc, deg - 1)
    el_j = dolfin.FiniteElement('BDM', muc, deg)
    el_DG0 = dolfin.FiniteElement('DG', muc, 0)
    el = dolfin.MixedElement([el_w, el_j])
    space = dolfin.FunctionSpace(mesh, el)
    DG0 = dolfin.FunctionSpace(mesh, el_DG0)
    fsr.register(space)
    facet_normal = dolfin.FacetNormal(mesh)
    xyz = dolfin.SpatialCoordinate(mesh)

    trial = dolfin.Function(space)
    test = dolfin.TestFunction(space)

    w, c = dolfin.split(trial)
    v, phi = dolfin.split(test)

    sympy_exprs = derive_exprs()
    exprs = {
        k: sympy_dolfin_printer.to_ufl(sympy_exprs['R'], mesh, v)
        for k, v in sympy_exprs['quantities'].items()
    }

    f = exprs['f']
    w0 = dolfin.project(dolfin.conditional(dolfin.gt(xyz[0], 0.5), 1.0, 0.3),
                        DG0)
    w_BC = exprs['w']

    dx = dolfin.dx()
    form = (+v * dolfin.div(c) * dx - v * f * dx +
            dolfin.exp(w + w0) * dolfin.dot(phi, c) * dx +
            dolfin.div(phi) * w * dx -
            (w_BC - w0) * dolfin.dot(phi, facet_normal) * dolfin.ds() -
            (w0('-') - w0('+')) * dolfin.dot(phi('+'), facet_normal('+')) *
            dolfin.dS())

    solver = NewtonSolver(form,
                          trial, [],
                          parameters=dict(relaxation_parameter=1.0,
                                          maximum_iterations=15,
                                          extra_iterations=10,
                                          relative_tolerance=1e-6,
                                          absolute_tolerance=1e-7))

    solver.solve()

    with closing(XdmfPlot("out/qflop_test.xdmf", fsr)) as X:
        CG1 = dolfin.FunctionSpace(mesh, dolfin.FiniteElement('CG', muc, 1))
        X.add('w0', 1, w0, CG1)
        X.add('w_c', 1, w + w0, CG1)
        X.add('w_e', 1, exprs['w'], CG1)
        X.add('f', 1, f, CG1)
        X.add('cx_c', 1, c[0], CG1)
        X.add('cx_e', 1, exprs['c'][0], CG1)
Ejemplo n.º 8
0
 def _setup_energy(self, rho, vel, gvec, x0):
     """
     Calculate kinetic and potential energy
     """
     x = df.SpatialCoordinate(self.mesh)
     self._form_E_k = Form(1 / 2 * rho * dot(vel, vel) *
                           dx(domain=self.mesh))
     self._form_E_p = Form(rho * dot(-gvec, x - x0) * dx(domain=self.mesh))
Ejemplo n.º 9
0
def sympy_to_ufl(R, mesh, expr, syms=None, **kwargs):
    syms = syms or dict()
    dim = mesh.geometry().dim()
    coord = dolfin.SpatialCoordinate(mesh)
    syms.update(zip(R.varlist, coord))
    kwargs.setdefault('dim', dim)
    kwargs.setdefault('reference_frame', R)
    return sympy_to_ufl_base(expr, syms, **kwargs)
Ejemplo n.º 10
0
def test_assemble_functional():
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 12, 12)
    M = 1.0 * dx(domain=mesh)
    value = dolfin.fem.assemble(M)
    assert value == pytest.approx(1.0, 1e-12)
    x = dolfin.SpatialCoordinate(mesh)
    M = x[0] * dx(domain=mesh)
    value = dolfin.fem.assemble(M)
    assert value == pytest.approx(0.5, 1e-12)
Ejemplo n.º 11
0
def test_probes(x, mesh1):
    el = dolfin.FiniteElement('BDM', mesh1.ufl_cell(), 2)
    W = dolfin.FunctionSpace(mesh1, el)
    z = dolfin.SpatialCoordinate(mesh1)
    expr = dolfin.as_vector((z[0], z[1]))
    w = dolfin.project(expr, W)
    ps = Probes(W)
    p = ps.probe(x)
    print(x, p(w), w(x))
    assert (p(w) == w(x)).all()
Ejemplo n.º 12
0
def CellCentroid(mesh):
    '''[DG0]^d function that evals on cell to its center of mass'''
    V = df.VectorFunctionSpace(mesh, 'DG', 0)
    v = df.TestFunction(V)

    hK = df.CellVolume(mesh)
    x = df.SpatialCoordinate(mesh)

    c = df.Function(V)
    df.assemble((1 / hK) * df.inner(x, v) * df.dx, tensor=c.vector())

    return c
Ejemplo n.º 13
0
def rigid_motion_term(mesh, u, r):
    position = dolfin.SpatialCoordinate(mesh)
    RM = [
        Constant((1, 0, 0)),
        Constant((0, 1, 0)),
        Constant((0, 0, 1)),
        dolfin.cross(position, Constant((1, 0, 0))),
        dolfin.cross(position, Constant((0, 1, 0))),
        dolfin.cross(position, Constant((0, 0, 1))),
    ]

    return sum(dolfin.dot(u, zi) * r[i] * dolfin.dx for i, zi in enumerate(RM))
Ejemplo n.º 14
0
    def setUp(self):
        self.mesh = mesh = dolfin.UnitSquareMesh(20, 2, "left")
        self.DG0_element = DG0e = dolfin.FiniteElement("DG", mesh.ufl_cell(),
                                                       0)
        self.DG0v_element = DG0ve = dolfin.VectorElement(
            "DG", mesh.ufl_cell(), 0)
        self.DG0 = DG0 = dolfin.FunctionSpace(mesh, DG0e)
        self.DG0v = DG0v = dolfin.FunctionSpace(mesh, DG0ve)

        self.fsr = fsr = FunctionSubspaceRegistry()
        fsr.register(DG0)
        fsr.register(DG0v)

        self.cellmid = cm = CellMidpointExpression(mesh, element=DG0ve)
        self.n = n = dolfin.FacetNormal(mesh)

        self.u = u = dolfin.Function(DG0)
        self.v = v = dolfin.TestFunction(DG0)

        u_bc = dolfin.Expression('x[0]', degree=2)

        x = dolfin.SpatialCoordinate(mesh)
        self.rho = rho = dolfin.conditional(
            dolfin.lt((x[0] - 0.5)**2 + (x[1] - 0.5)**2, 0.2**2), 0.0, 0.0)

        dot = dolfin.dot
        cellsize = dolfin.CellSize(mesh)
        self.h = h = cm('+') - cm('-')
        self.h_boundary = h_boundary = 2 * n * dot(x - cm, n)
        self.E = E = h / dot(h, h) * (u('-') - u('+'))
        self.E_boundary = E_boundary = h_boundary / dot(
            h_boundary, h_boundary) * (u - u_bc)
        dS = dolfin.dS

        eps = 1e-8

        class BL(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return abs(x[0]) < eps

        class BR(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return abs(x[0] - 1) < eps

        ff = dolfin.FacetFunction('size_t', mesh, 0)
        BL().mark(ff, 1)
        BR().mark(ff, 1)

        ds = dolfin.Measure('ds', domain=mesh, subdomain_data=ff)

        self.F = (dot(E, n('+')) * v('+') * dS + dot(E, n('-')) * v('-') * dS -
                  v * rho * dolfin.dx + dot(E_boundary, n) * v * ds(1))
Ejemplo n.º 15
0
    def helper_test_roundtrip(self, dedup):
        mesh0 = dolfin.UnitSquareMesh(3, 5)
        uc0 = mesh0.ufl_cell()
        el0 = dolfin.FiniteElement('CG', uc0, 2)
        W0 = dolfin.FunctionSpace(mesh0, el0)
        u0 = dolfin.Function(W0)

        mf0 = dolfin.MeshFunction("size_t", mesh0, 1, 0)
        mf0.array()[:] = range(len(mf0.array()))

        x = dolfin.SpatialCoordinate(mesh0)
        dolfin.project(x[0] - x[1]**2, W0, function=u0)

        outdir = tempfile.mkdtemp('.solution_io')
        # atexit.register(partial(shutil.rmtree, outdir))
        outfile = os.path.join(outdir, 'test.yaml')

        man = DolfinH5Manager(outfile)

        with open(outfile, 'wt') as stream:
            yaml.dump(
                dict(mesh=mesh0, u=u0, mf=mf0),
                stream,
                Dumper=partial(XDumper, x_attr_dict=dict(
                    dolfin_h5_manager=man)))

        with open(outfile, 'rt') as h: print(h.read())

        if dedup:
            from h5dedup.dedup import DedupRepository
            repo = DedupRepository(outdir)
            repo.deduplicate_file_tree(outdir)

        with open(outfile, 'rt') as stream:
            r = yaml.load(stream, Loader=partial(XLoader, x_attr_dict=dict(
                dolfin_h5_manager=man)))

        mesh1 = dolfin.Mesh()
        r['mesh'].load_into(mesh1)

        W1 = dolfin.FunctionSpace(mesh1, el0)
        u1 = dolfin.Function(W1)
        r['u'].load_into(u1)

        mf1 = dolfin.MeshFunction("size_t", mesh1, 1, 0)
        r['mf'].load_into(mf1)

        u1_ = dolfin.project(u1, W0)

        self.assertLess(dolfin.assemble((u0-u1_)**2*dolfin.dx), 1e-26)
        self.assertEqual(tuple(mf0.array()), tuple(mf1.array()))
Ejemplo n.º 16
0
def Grad(u):
    '''Gradient in cylinderical (z, r, theta) coords'''
    z, r, th = df.SpatialCoordinate(u.ufl_domain().ufl_cargo())
    # Scalar
    if u.ufl_shape == ():
        return df.as_vector((u.dx(0), u.dx(1), (1/r)*u.dx(2)))

    # Ignore tensors for now
    assert len(u.ufl_shape) == 1
    # z r theta 
    uz, ur, uth = u[0], u[1], u[2]
    return df.as_matrix(((uz.dx(0),  uz.dx(1),  (1/r)*uz.dx(2)),
                         (ur.dx(0),  ur.dx(1),  (1/r)*ur.dx(2) - uth/r),
                         (uth.dx(0), uth.dx(1), (1/r)*uth.dx(2) + ur/r)))
Ejemplo n.º 17
0
def GradAxisym(u):
    '''Gradient in cylinderical axisymmetric (z, r) coords'''
    z, r = df.SpatialCoordinate(u.ufl_domain().ufl_cargo())
    # Scalar
    if u.ufl_shape == ():
        return df.as_vector((u.dx(0), u.dx(1), df.Constant(0)*u))

    # Ignore tensors for now
    assert len(u.ufl_shape) == 1
    # z r theta 
    uz, ur = u[0], u[1]
    return df.as_matrix(((uz.dx(0),  uz.dx(1),  df.Constant(0)*uz),
                         (ur.dx(0),  ur.dx(1),  df.Constant(0)*ur),
                         (df.Constant(0)*uz, df.Constant(0)*ur, ur/r)))
Ejemplo n.º 18
0
def test_complex_assembly_solve():
    """Solve a positive definite helmholtz problem and verify solution
    with the method of manufactured solutions

    """

    degree = 3
    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 20, 20)
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree)
    V = dolfin.function.functionspace.FunctionSpace(mesh, P)

    x = dolfin.SpatialCoordinate(mesh)

    # Define source term
    A = 1 + 2 * (2 * np.pi)**2
    f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1])

    # Variational problem
    u = dolfin.function.argument.TrialFunction(V)
    v = dolfin.function.argument.TestFunction(V)
    C = 1 + 1j
    a = C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx
    L = inner(f, v) * dx

    # Assemble
    A = dolfin.fem.assemble(a)
    b = dolfin.fem.assemble(L)

    # Create solver
    solver = dolfin.cpp.la.PETScKrylovSolver(mesh.mpi_comm())
    dolfin.cpp.la.PETScOptions.set("ksp_type", "preonly")
    dolfin.cpp.la.PETScOptions.set("pc_type", "lu")
    solver.set_from_options()
    x = dolfin.cpp.la.PETScVector()
    solver.set_operator(A)
    solver.solve(x, b)

    # Reference Solution
    @dolfin.function.expression.numba_eval
    def ref_eval(values, x, cell_idx):
        values[:,
               0] = np.cos(2 * np.pi * x[:, 0]) * np.cos(2 * np.pi * x[:, 1])

    u_ref = dolfin.interpolate(dolfin.Expression(ref_eval), V)

    xnorm = x.norm(dolfin.cpp.la.Norm.l2)
    x_ref_norm = u_ref.vector().norm(dolfin.cpp.la.Norm.l2)
    assert np.isclose(xnorm, x_ref_norm)
Ejemplo n.º 19
0
def get_cavity_volume_form(mesh, u=None, xshift=0.0):

    from . import kinematics

    shift = Constant((xshift, 0.0, 0.0))
    X = dolfin.SpatialCoordinate(mesh) - shift
    N = dolfin.FacetNormal(mesh)

    if u is None:
        vol_form = (-1.0 / 3.0) * dolfin.dot(X, N)
    else:
        F = kinematics.DeformationGradient(u)
        J = kinematics.Jacobian(F)
        vol_form = (-1.0 / 3.0) * dolfin.dot(X + u, J * dolfin.inv(F).T * N)

    return vol_form
Ejemplo n.º 20
0
    def strain_rate_tensor(self, u):
        r"""Define the symmetric strain-rate tensor

        :param u: The velocity field (2D).
        :return: The strain rate tensor.
        """
        r = dolfin.SpatialCoordinate(self._mesh)[0]
        ur = u[0]
        uz = u[1]
        ur_r = ur.dx(0)
        ur_z = ur.dx(1)
        uz_r = uz.dx(0)
        uz_z = uz.dx(1)
        return dolfin.sym(
            dolfin.as_tensor([[ur_r, 0, 0.5 * (uz_r + ur_z)], [0, ur / r, 0],
                              [0.5 * (uz_r + ur_z), 0, uz_z]]))
Ejemplo n.º 21
0
def wind_number(mesh, points):
    '''Of a loop'''
    assert is_loop(mesh)
    assert mesh.geometry().dim() == 2
    assert points.ndim == 2

    x = df.SpatialCoordinate(mesh)
    tan = TangentCurve(mesh)
    c = df.Constant([0, 0])

    R = df.Constant(((0, 1), (-1, 0)))
    L = df.inner(
        (x - c) / (2 * df.pi) / df.dot(x - c, x - c), df.dot(R, tan)) * df.dx

    return np.fromiter(((c.assign(df.Constant(point)), df.assemble(L))[-1]
                        for point in points),
                       dtype=float)
    def computeTangent(self):

        dy = df.Measure('dx', self.mesh)
        vol = df.assemble(df.Constant(1.0) * dy)
        y = df.SpatialCoordinate(self.mesh)
        Eps = df.Constant(((0., 0.), (0., 0.)))  # just placeholder

        form = self.multiscaleModel(self.mesh, self.sigmaLaw, Eps, self.others)
        a, f, bcs, W = form()

        start = timer()
        A = mp.block_assemble(a)
        if (len(bcs) > 0):
            bcs.apply(A)

        # decompose just once (the faster for single process)
        solver = df.PETScLUSolver('superlu')
        sol = mp.BlockFunction(W)

        end = timer()
        print('time assembling system', end - start)

        for i in range(self.nvoigt):
            start = timer()
            Eps.assign(df.Constant(macro_strain(i)))
            F = mp.block_assemble(f)
            if (len(bcs) > 0):
                bcs.apply(F)

            solver.solve(A, sol.block_vector(), F)
            sol.block_vector().block_function().apply("to subfunctions")

            sig_mu = self.sigmaLaw(df.dot(Eps, y) + sol[0])
            sigma_hom = Integral(sig_mu, dy, (2, 2)) / vol

            self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]]

            end = timer()
            print('time in solving system', end - start)

        print(self.Chom_)

        # from the second run onwards, just returns
        self.getTangent = self.getTangent_

        return self.Chom_
Ejemplo n.º 23
0
    def test_extract_nodal_CG1(self):
        mesh = dolfin.UnitSquareMesh(16, 16)
        el = dolfin.VectorElement("CG", mesh.ufl_cell(), 1)
        CG1 = dolfin.FunctionSpace(mesh, el)

        e_expr = dolfin.Expression(("x[0]-2*exp(x[1])", "x[0]*x[1]"), degree=1)
        x = dolfin.SpatialCoordinate(mesh)
        e_ufl = dolfin.as_vector((x[0] - 2 * dolfin.exp(x[1]), x[0] * x[1]))

        u0 = dolfin.interpolate(e_expr, CG1)

        u_nodal = interpolate(e_ufl, CG1)  # nodal values
        u_proj = dolfin.project(e_ufl, CG1)  # projection/averaging

        maxdiff = self.maxdiff

        self.assertLess(maxdiff(u0, u_nodal), 2 * dolfin.DOLFIN_EPS)
        self.assertGreater(maxdiff(u0, u_proj), 2 * dolfin.DOLFIN_EPS)
Ejemplo n.º 24
0
    def __init__(
        self,
        mesh,
        dmu,
        approx="project",
        displacement_space="CG_2",
        interpolation_space="CG_1",
        description="",
    ):
        ModelObservation.__init__(self,
                                  mesh,
                                  target_space="R_0",
                                  description=description)

        approxs = ["project", "interpolate", "original"]
        msg = 'Expected "approx" for be one of {}, got {}'.format(
            approxs, approx)
        assert approx in approxs, msg
        self._approx = approx

        # These spaces are only used if you want to project
        # or interpolate the displacement before assigning it
        # Space for interpolating the displacement if needed
        family, degree = interpolation_space.split("_")
        self._interpolation_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))

        # Displacement space
        family, degree = displacement_space.split("_")
        self._displacement_space = dolfin.VectorFunctionSpace(
            mesh, family, int(degree))

        self._X = dolfin.SpatialCoordinate(mesh)
        self._N = dolfin.FacetNormal(mesh)
        assert isinstance(dmu, dolfin.Measure)
        self._dmu = dmu

        name = "EndoArea {}".format(self)
        self._endoarea = dolfin_adjoint.Constant(dolfin.assemble(
            dolfin.Constant(1.0) * dmu),
                                                 name=name)
Ejemplo n.º 25
0
def test_complex_assembly():
    """Test assembly of complex matrices and vectors"""

    mesh = dolfin.generation.UnitSquareMesh(dolfin.MPI.comm_world, 10, 10)
    P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2)
    V = dolfin.function.functionspace.FunctionSpace(mesh, P2)

    u = dolfin.function.argument.TrialFunction(V)
    v = dolfin.function.argument.TestFunction(V)

    g = dolfin.function.constant.Constant(-2 + 3.0j)
    j = dolfin.function.constant.Constant(1.0j)

    a_real = inner(u, v) * dx
    L1 = inner(g, v) * dx

    bnorm = dolfin.fem.assemble(L1).norm(dolfin.cpp.la.Norm.l1)
    b_norm_ref = abs(-2 + 3.0j)
    assert np.isclose(bnorm, b_norm_ref)
    A0_norm = dolfin.fem.assemble(a_real).norm(dolfin.cpp.la.Norm.frobenius)

    x = dolfin.SpatialCoordinate(mesh)

    a_imag = j * inner(u, v) * dx
    f = 1j * ufl.sin(2 * np.pi * x[0])
    L0 = inner(f, v) * dx
    A1_norm = dolfin.fem.assemble(a_imag).norm(dolfin.cpp.la.Norm.frobenius)
    assert np.isclose(A0_norm, A1_norm)
    b1_norm = dolfin.fem.assemble(L0).norm(dolfin.cpp.la.Norm.l2)

    a_complex = (1 + j) * inner(u, v) * dx
    f = ufl.sin(2 * np.pi * x[0])
    L2 = inner(f, v) * dx
    A2_norm = dolfin.fem.assemble(a_complex).norm(dolfin.cpp.la.Norm.frobenius)
    assert np.isclose(A1_norm, A2_norm / np.sqrt(2))
    b2_norm = dolfin.fem.assemble(L2).norm(dolfin.cpp.la.Norm.l2)
    assert np.isclose(b2_norm, b1_norm)
Ejemplo n.º 26
0
def comp_axisymmetric_pure_neumann(mat_obj, mesh_obj, bc, omega, save_path):
    E = mat_obj.E
    rho = mat_obj.rho
    nu = mat_obj.nu

    mesh = mesh_obj.create()
    Rext = mesh_obj.Rext
    Rint = mesh_obj.Rint

    # rename x[0], x[1] by x, y
    x, y = df.SpatialCoordinate(mesh)

    dim = mesh.topology().dim()

    cell_markers = df.MeshFunction("size_t", mesh, dim)
    facet_markers = df.MeshFunction("size_t", mesh, dim - 1)

    coord = mesh.coordinates()

    class OuterRadius(df.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0]**2 + x[1]**2 >= Rext**2 - 1e-3

    class InnerRadius(df.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and x[0]**2 + x[1]**2 <= Rint**2 + 1e-3

    OuterRadius().mark(facet_markers, 1)
    InnerRadius().mark(facet_markers, 2)

    df.File(save_path + 'cell_markers.pvd') << cell_markers
    df.File(save_path + 'facet_markers.pvd') << facet_markers

    # Create mesh and define function space
    V = df.FunctionSpace(mesh, "CG", 1)
    # =========================== Define Finite Element ===========================
    degree = 1  #P1 table of periodic
    # CG: Continuous Galerkin
    V_ele = df.FiniteElement("CG", mesh.ufl_cell(), degree)  # scalar, Ex: u
    R_ele = df.FiniteElement("R", mesh.ufl_cell(), 0)  # scalar, Ex: u
    # Vector element # akternative : manually define vector function : better for 3D adaptation than above
    total_ele = df.MixedElement([V_ele, R_ele])
    W = df.FunctionSpace(mesh, total_ele)

    # Define trial function
    dunks = df.TrialFunction(W)
    (du, dc) = df.split(dunks)

    # Define variational problem
    tunks = df.TestFunction(W)
    (tu, tc) = df.split(tunks)

    # displacement in radial direction u(x,y)
    unks = df.Function(W)

    #(u, c) = df.split(unks)

    class THETA(df.UserExpression):
        def eval(self, values, x):
            values[0] = math.atan2(x[1], x[0])

        def value_shape(self):
            #return (1,) # vector
            return ()  # scalar

    theta = THETA(degree=1)

    #theta_int = df.interpolate(theta, df.FunctionSpace(mesh, "DG", 0))
    #df.File(save_path + 'theta.pvd') << theta_int

    class RADIUS(df.UserExpression):
        def eval(self, values, x):
            values[0] = df.sqrt(x[0] * x[0] + x[1] * x[1])

        def value_shape(self):
            return ()  # scalar

    r = RADIUS(degree=1)

    # strain radial
    def epsilon_r(du):
        return 1.0 / r * (x * df.Dx(du, 0) + y * df.Dx(du, 1))

    # strain circumferential
    def epsilon_theta(du):
        return du / df.sqrt(x**2 + y**2)

    # radial stress # train-stress relation
    def sigma_r(du):
        return E / (1.0 - nu**2) * (epsilon_r(du) + nu * epsilon_theta(du))

    # circumferential stress
    def sigma_theta(du):
        return E / (1.0 - nu**2) * (nu * epsilon_r(du) + epsilon_theta(du))

    # Weak form
    dFu = r * sigma_r(du) * epsilon_r(tu) * df.dx(0)
    dFu = dFu + sigma_theta(du) * tu * df.dx(0)
    dFu = dFu + dc * tu * df.dx(0)
    dFu = dFu - rho * omega**2 * r**2 * tu * df.dx(0)
    dFc = du * tc * df.dx(1)

    dFu = r * sigma_r(du) * epsilon_r(tu) * df.dx
    dFu = dFu + sigma_theta(du) * tu * df.dx
    dFu = dFu + dc * tu * df.dx
    dFu = dFu - rho * omega**2 * r**2 * tu * df.dx
    dFc = du * tc * df.dx

    dF = dFu + dFc

    # residual
    #F = df.action(dF, unks)

    a = df.lhs(dF)
    L = df.rhs(dF)

    df.solve(a == L, unks)

    (_u, _c) = unks.split(True)

    u_pro = df.project(_u, V)
    u_pro.rename('dis u [m]', 'dis u [m]')

    # displacement
    df.File(save_path + 'displacement.pvd') << u_pro

    # compute stresses
    sigma_r_pro = df.project(sigma_r(_u), V)
    sigma_r_pro.rename('sigma_r [Pa]', 'sigma_r [Pa]')
    df.File(save_path + 'sigma_r.pvd') << sigma_r_pro

    sigma_theta_pro = df.project(sigma_theta(_u), V)
    sigma_theta_pro.rename('sigma_theta [Pa]', 'sigma_theta [Pa]')
    df.File(save_path + 'sigma_theta.pvd') << sigma_theta_pro

    # compute von Mises stress
    def von_mises_stress(sigma_r, sigma_theta):
        return df.sqrt(sigma_r**2 + sigma_theta**2 - sigma_r * sigma_theta)

    von_stress_pro = df.project(von_mises_stress(sigma_r(_u), sigma_theta(_u)),
                                V)
    von_stress_pro.rename('von Mises Stress [Pa]', 'von Mises Stress [Pa]')
    df.File(save_path + 'von_mises_stress.pvd') << von_stress_pro
Ejemplo n.º 27
0
def define_dg_equations(
    u,
    v,
    p,
    q,
    lm_trial,
    lm_test,
    simulation,
    include_hydrostatic_pressure,
    incompressibility_flux_type,
    use_grad_q_form,
    use_grad_p_form,
    use_stress_divergence_form,
    velocity_continuity_factor_D12=0,
    pressure_continuity_factor=0,
):
    """
    Define the coupled equations. Also used by the SIMPLE and IPCS-A solvers

    Weak form of the Navier-Stokes eq. with discontinuous elements

    :type simulation: ocellaris.Simulation
    """
    sim = simulation
    show = sim.log.info
    show('    Creating DG weak form with BCs')
    show('        include_hydrostatic_pressure = %r' %
         include_hydrostatic_pressure)
    show('        incompressibility_flux_type = %s' %
         incompressibility_flux_type)
    show('        use_grad_q_form = %r' % use_grad_q_form)
    show('        use_grad_p_form = %r' % use_grad_p_form)
    show('        use_stress_divergence_form = %r' %
         use_stress_divergence_form)
    show('        velocity_continuity_factor_D12 = %r' %
         velocity_continuity_factor_D12)
    show('        pressure_continuity_factor = %r' %
         pressure_continuity_factor)

    mpm = sim.multi_phase_model
    mesh = sim.data['mesh']
    u_conv = sim.data['u_conv']
    dx = dolfin.dx(domain=mesh)
    dS = dolfin.dS(domain=mesh)

    c1, c2, c3 = sim.data['time_coeffs']
    dt = sim.data['dt']
    g = sim.data['g']
    n = dolfin.FacetNormal(mesh)
    x = dolfin.SpatialCoordinate(mesh)

    # Fluid properties
    rho = mpm.get_density(0)
    nu = mpm.get_laminar_kinematic_viscosity(0)
    mu = mpm.get_laminar_dynamic_viscosity(0)

    # Hydrostatic pressure correction
    if include_hydrostatic_pressure:
        p += sim.data['p_hydrostatic']

    # Start building the coupled equations
    eq = 0

    # ALE mesh velocities
    if sim.mesh_morpher.active:
        u_mesh = sim.data['u_mesh']

        # Either modify the convective velocity or just include the mesh
        # velocity on cell integral form. Only activate one of the lines below
        # PS: currently the UFL form splitter (used in e.g. IPCS-A) has a
        #     problem with line number 2, but the Coupled solver handles
        #     both options with approximately the same resulting convergence
        #     errors on the Taylor-Green test case (TODO: fix form splitter)
        u_conv -= u_mesh
        # eq -= dot(div(rho * dolfin.outer(u, u_mesh)), v) * dx

        # Divergence of u should balance expansion/contraction of the cell K
        # ∇⋅u = -∂x/∂t       (See below for definition of the ∇⋅u term)
        # THIS IS SOMEWHAT EXPERIMENTAL
        cvol_new = dolfin.CellVolume(mesh)
        cvol_old = sim.data['cvolp']
        eq += (cvol_new - cvol_old) / dt * q * dx

    # Elliptic penalties
    penalty_dS, penalty_ds, D11, D12 = navier_stokes_stabilization_penalties(
        sim, nu, velocity_continuity_factor_D12, pressure_continuity_factor)
    yh = 1 / penalty_ds

    # Upwind and downwind velocities
    w_nU = (dot(u_conv, n) + abs(dot(u_conv, n))) / 2.0
    w_nD = (dot(u_conv, n) - abs(dot(u_conv, n))) / 2.0

    # Lagrange multiplicator to remove the pressure null space
    # ∫ p dx = 0
    if lm_trial is not None:
        eq = (p * lm_test + q * lm_trial) * dx

    # Momentum equations
    for d in range(sim.ndim):
        up = sim.data['up%d' % d]
        upp = sim.data['upp%d' % d]

        # Divergence free criterion
        # ∇⋅u = 0
        if incompressibility_flux_type == 'central':
            u_hat_p = avg(u[d])
        elif incompressibility_flux_type == 'upwind':
            assert use_grad_q_form, 'Upwind only implemented for grad_q_form'
            switch = dolfin.conditional(dolfin.gt(w_nU('+'), 0.0), 1.0, 0.0)
            u_hat_p = switch * u[d]('+') + (1 - switch) * u[d]('-')

        if use_grad_q_form:
            eq -= u[d] * q.dx(d) * dx
            eq += (u_hat_p + D12[d] * jump(u, n)) * jump(q) * n[d]('+') * dS
        else:
            eq += q * u[d].dx(d) * dx
            eq -= (avg(q) - dot(D12, jump(q, n))) * jump(u[d]) * n[d]('+') * dS

        # Time derivative
        # ∂(ρu)/∂t
        eq += rho * (c1 * u[d] + c2 * up + c3 * upp) / dt * v[d] * dx

        # Convection:
        # -w⋅∇(ρu)
        flux_nU = u[d] * w_nU
        flux = jump(flux_nU)
        eq -= u[d] * dot(grad(rho * v[d]), u_conv) * dx
        eq += flux * jump(rho * v[d]) * dS

        # Stabilizing term when w is not divergence free
        eq += 1 / 2 * div(u_conv) * u[d] * v[d] * dx

        # Diffusion:
        # -∇⋅μ∇u
        eq += mu * dot(grad(u[d]), grad(v[d])) * dx

        # Symmetric Interior Penalty method for -∇⋅μ∇u
        eq -= avg(mu) * dot(n('+'), avg(grad(u[d]))) * jump(v[d]) * dS
        eq -= avg(mu) * dot(n('+'), avg(grad(v[d]))) * jump(u[d]) * dS

        # Symmetric Interior Penalty coercivity term
        eq += penalty_dS * jump(u[d]) * jump(v[d]) * dS

        # -∇⋅μ(∇u)^T
        if use_stress_divergence_form:
            eq += mu * dot(u.dx(d), grad(v[d])) * dx
            eq -= avg(mu) * dot(n('+'), avg(u.dx(d))) * jump(v[d]) * dS
            eq -= avg(mu) * dot(n('+'), avg(v.dx(d))) * jump(u[d]) * dS

        # Pressure
        # ∇p
        if use_grad_p_form:
            eq += v[d] * p.dx(d) * dx
            eq -= (avg(v[d]) + D12[d] * jump(v, n)) * jump(p) * n[d]('+') * dS
        else:
            eq -= p * v[d].dx(d) * dx
            eq += (avg(p) - dot(D12, jump(p, n))) * jump(v[d]) * n[d]('+') * dS

        # Pressure continuity stabilization. Needed for equal order discretization
        if D11 is not None:
            eq += D11 * dot(jump(p, n), jump(q, n)) * dS

        # Body force (gravity)
        # ρ g
        eq -= rho * g[d] * v[d] * dx

        # Other sources
        for f in sim.data['momentum_sources']:
            eq -= f[d] * v[d] * dx

        # Penalty forcing zones
        for fz in sim.data['forcing_zones'].get('u', []):
            eq += fz.penalty * fz.beta * (u[d] - fz.target[d]) * v[d] * dx

        # Boundary conditions that do not couple the velocity components
        # The BCs are imposed for each velocity component u[d] separately

        eq += add_dirichlet_bcs(sim, d, u, p, v, q, rho, mu, n, w_nU, w_nD,
                                penalty_ds, use_grad_q_form, use_grad_p_form)

        eq += add_neumann_bcs(sim, d, u, p, v, q, rho, mu, n, w_nU, w_nD,
                              penalty_ds, use_grad_q_form, use_grad_p_form)

        eq += add_robin_bcs(sim, d, u, p, v, q, rho, mu, n, w_nU, w_nD, yh,
                            use_grad_q_form, use_grad_p_form)

        eq += add_outlet_bcs(sim, d, u, p, v, q, rho, mu, n, w_nU, w_nD, g, x,
                             use_grad_q_form, use_grad_p_form)

    # Boundary conditions that couple the velocity components
    # Decomposing the velocity into wall normal and parallel parts

    eq += add_slip_bcs(sim, u, p, v, q, rho, mu, n, w_nU, w_nD, penalty_ds,
                       use_grad_q_form, use_grad_p_form)

    return eq
Ejemplo n.º 28
0
 def x(self):
     try:
         return self._x
     except AttributeError:
         self._x = dolfin.SpatialCoordinate(self.mesh)
         return self._x
Ejemplo n.º 29
0
if really_squished_mesh:
    extent, NM = (0., 0., 0.02, 1.0), (1, 20)
else:
    extent, NM = (0., 0., 1.0, 1.0), (30, 30)
mesh = dolfin.RectangleMesh(tuple_to_point(extent[:2]),
                            tuple_to_point(extent[2:]), *NM)

muc = mesh.ufl_cell()
I_el = dolfin.FiniteElement('CG', muc, 2)
space = dolfin.FunctionSpace(mesh, I_el)

u = dolfin.Function(space)
test_function = dolfin.TestFunction(space)

facet_normal = dolfin.FacetNormal(mesh)
x = dolfin.SpatialCoordinate(mesh)


def lower_boundary(x, on_boundary):
    return on_boundary and (abs(x[1] - 0) < 1e-10)


def left_boundary(x, on_boundary):
    return on_boundary and (abs(x[0] - 0) < 1e-10)


def right_boundary(x, on_boundary):
    return on_boundary and (abs(x[0] - 1) < 1e-10)


def make_form(I, v, omega, beta, S):
Ejemplo n.º 30
0
print("start0")

import dolfin as df

print("start")

mesh = df.RectangleMesh(df.Point(1.0, 1.0), df.Point(2.0, 2.0), 10, 10)
# mesh = UnitIntervalMesh(10)

el = df.FiniteElement("Lagrange", mesh.ufl_cell(), degree=1)
V = df.FunctionSpace(mesh, el)
x = df.SpatialCoordinate(mesh)

p_code = """
#include <pybind11/pybind11.h>
#include <pybind11/eigen.h>

#include <cmath>
#include <boost/math/special_functions/bessel.hpp>

using namespace std;
using namespace boost::math;

namespace py = pybind11;

#include <dolfin/function/Expression.h>

class Pressure : public dolfin::Expression
{
public: