Example #1
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
def testFacetArea():
    references = [(UnitIntervalMesh(MPI.comm_world, 1), 2, 2), (UnitSquareMesh(
        MPI.comm_world, 1, 1), 4, 4), (UnitCubeMesh(MPI.comm_world, 1, 1, 1),
                                       6, 3)]
    for mesh, surface, ref_int in references:
        c0 = ufl.FacetArea(mesh)
        c1 = dolfin.FacetArea(mesh)
        assert (c0)
        assert (c1)
Example #3
0
def testFacetArea():

    references = [(UnitIntervalMesh(1), 2, 2),\
                  (UnitSquareMesh(1,1), 4, 4),\
                  (UnitCubeMesh(1,1,1), 6, 3)]
    for mesh, surface, ref_int in references:
        c = Constant(1, mesh.ufl_cell())  # FIXME
        c0 = ufl.FacetArea(mesh)
        c1 = dolfin.FacetArea(mesh)
        assert round(assemble(c * dx(mesh)) - 1, 7) == 0
        assert round(assemble(c * ds(mesh)) - surface, 7) == 0
        assert round(assemble(c0 * ds(mesh)) - ref_int, 7) == 0
        assert round(assemble(c1 * ds(mesh)) - ref_int, 7) == 0
Example #4
0
 def testFacetArea(self):
     if MPI.size(mpi_comm_world()) == 1:
         references = [(UnitIntervalMesh(1), 2, 2),\
                       (UnitSquareMesh(1,1), 4, 4),\
                       (UnitCubeMesh(1,1,1), 6, 3)]
         for mesh, surface, ref_int in references:
             c = Constant(1, mesh.ufl_cell())  # FIXME
             c0 = ufl.FacetArea(mesh)
             c1 = dolfin.FacetArea(mesh)
             self.assertAlmostEqual(assemble(c * dx, mesh=mesh), 1)
             self.assertAlmostEqual(assemble(c * ds, mesh=mesh), surface)
             self.assertAlmostEqual(assemble(c0 * ds, mesh=mesh), ref_int)
             self.assertAlmostEqual(assemble(c1 * ds, mesh=mesh), ref_int)
Example #5
0
def _CenterDistance(mesh, Center):
    '''Magnitude of Centervector as a DLT function'''
    if mesh.topology().dim() > 1:
        L = df.FunctionSpace(mesh, 'Discontinuous Lagrange Trace', 0)
    else:
        L = df.FunctionSpace(mesh, 'CG', 1)

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

    cc = Center(mesh)
    distance = df.Function(L)
    # We use P0 projection
    df.assemble(1 / fK('+') *
                df.inner(df.sqrt(df.dot(cc('+'), cc('+'))), l('+')) * df.dS +
                1 / fK * df.inner(df.sqrt(df.dot(cc, cc)), l) * df.ds,
                tensor=distance.vector())

    return distance
Example #6
0
    def define_coupled_equation(self):
        """
        Setup the coupled Navier-Stokes equation

        This implementation assembles the full LHS and RHS each time they are needed
        """
        sim = self.simulation
        mpm = sim.multi_phase_model
        mesh = sim.data['mesh']
        Vcoupled = sim.data['Vcoupled']
        u_conv = sim.data['u_conv']

        # Unpack the coupled trial and test functions
        uc = dolfin.TrialFunction(Vcoupled)
        vc = dolfin.TestFunction(Vcoupled)
        ulist = []
        vlist = []
        sigmas, taus = [], []
        for d in range(sim.ndim):
            ulist.append(uc[d])
            vlist.append(vc[d])
            indices = list(
                range(1 + sim.ndim * (d + 1), 1 + sim.ndim * (d + 2)))
            sigmas.append([uc[i] for i in indices])
            taus.append([vc[i] for i in indices])

        u = dolfin.as_vector(ulist)
        v = dolfin.as_vector(vlist)
        p = uc[sim.ndim]
        q = vc[sim.ndim]
        sigma = dolfin.as_tensor(sigmas)
        tau = dolfin.as_tensor(taus)

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

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

        # 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
        u_uw_s = dolfin.conditional(dolfin.gt(dot(u_conv, n), 0.0), 1.0,
                                    0.0)('+')
        u_uw = u_uw_s * u('+') + (1 - u_uw_s) * u('-')

        # LDG penalties
        # kappa_0 = Constant(4.0)
        # kappa = mu*kappa_0/h
        C11 = avg(mu / h)
        D11 = avg(h / mu)
        C12 = 0.2 * n('+')
        D12 = 0.2 * n('+')

        def ojump(v, n):
            return outer(v, n)('+') + outer(v, n)('-')

        # Interior facet fluxes
        # u_hat_dS = avg(u)
        # sigma_hat_dS = avg(sigma) - avg(kappa)*ojump(u, n)
        # p_hat_dS = avg(p)
        u_hat_s_dS = avg(u) + dot(ojump(u, n), C12)
        u_hat_p_dS = avg(u) + D11 * jump(p, n) + D12 * jump(u, n)
        sigma_hat_dS = avg(sigma) - C11 * ojump(u, n) - outer(
            jump(sigma, n), C12)
        p_hat_dS = avg(p) - dot(D12, jump(p, n))

        # Time derivative
        up = sim.data['up']
        upp = sim.data['upp']
        eq = rho * dot(c1 * u + c2 * up + c3 * upp, v) / dt * dx

        # LDG equation 1
        eq += inner(sigma, tau) * dx
        eq += dot(u, div(mu * tau)) * dx
        eq -= dot(u_hat_s_dS, jump(mu * tau, n)) * dS

        # LDG equation 2
        eq += (inner(sigma, grad(v)) - p * div(v)) * dx
        eq -= (inner(sigma_hat_dS, ojump(v, n)) - p_hat_dS * jump(v, n)) * dS
        eq -= dot(u, div(outer(v, rho * u_conv))) * dx
        eq += rho('+') * dot(u_conv('+'), n('+')) * dot(u_uw, v('+')) * dS
        eq += rho('-') * dot(u_conv('-'), n('-')) * dot(u_uw, v('-')) * dS
        momentum_sources = sim.data['momentum_sources'] + [rho * g]
        eq -= dot(sum(momentum_sources), v) * dx

        # LDG equation 3
        eq -= dot(u, grad(q)) * dx
        eq += dot(u_hat_p_dS, jump(q, n)) * dS

        # Dirichlet boundary
        dirichlet_bcs = get_collected_velocity_bcs(sim, 'dirichlet_bcs')
        for ds, u_bc in dirichlet_bcs.items():
            # sigma_hat_ds = sigma - kappa*outer(u, n)
            sigma_hat_ds = sigma - C11 * outer(u - u_bc, n)
            u_hat_ds = u_bc
            p_hat_ds = p

            # LDG equation 1
            eq -= dot(u_hat_ds, dot(mu * tau, n)) * ds

            # LDG equation 2
            eq -= (inner(sigma_hat_ds, outer(v, n)) -
                   p_hat_ds * dot(v, n)) * ds
            eq += rho * w_nU * dot(u, v) * ds
            eq += rho * w_nD * dot(u_bc, v) * ds

            # LDG equation 3
            eq += dot(u_hat_ds, q * n) * ds

        # Neumann boundary
        neumann_bcs = get_collected_velocity_bcs(sim, 'neumann_bcs')
        assert not neumann_bcs
        for ds, du_bc in neumann_bcs.items():
            # Divergence free criterion
            if self.use_grad_q_form:
                eq += q * dot(u, n) * ds
            else:
                eq -= q * dot(u, n) * ds

            # Convection
            eq += rho * w_nU * dot(u, v) * ds

            # Diffusion
            u_hat_ds = u
            sigma_hat_ds = outer(du_bc, n) / mu
            eq -= dot(u_hat_ds, dot(mu * tau, n)) * ds
            eq -= inner(sigma_hat_ds, outer(v, n)) * ds

            # Pressure
            if not self.use_grad_p_form:
                eq += p * dot(v, n) * ds

        a, L = dolfin.system(eq)
        self.form_lhs = a
        self.form_rhs = L
        self.tensor_lhs = None
        self.tensor_rhs = None
Example #7
0
    def __init__(self, mesh, orientation):
        if orientation is None:
            # We assume convex domain and take center as ...
            orientation = mesh.coordinates().mean(axis=0)

        if isinstance(orientation, df.Mesh):
            # We set surface normal as outer with respect to orientation mesh
            assert orientation.id() in mesh.parent_entity_map

            n = df.FacetNormal(orientation)
            hA = df.FacetArea(orientation)
            # Project normal, we have a function on mesh
            DLT = df.VectorFunctionSpace(orientation,
                                         'Discontinuous Lagrange Trace', 0)
            n_ = df.Function(DLT)
            df.assemble((1 / hA) * df.inner(n, df.TestFunction(DLT)) * df.ds,
                        tensor=n_.vector())

            # Now we get it to manifold
            dx_ = df.Measure('dx', domain=mesh)
            V = df.VectorFunctionSpace(mesh, 'DG', 0)

            df.Function.__init__(self, V)

            hK = df.CellVolume(mesh)
            n_vec = xii.ii_convert(
                xii.ii_assemble(
                    (1 / hK) *
                    df.inner(xii.Trace(n_, mesh), df.TestFunction(V)) * dx_))

            self.vector()[:] = n_vec

            return None

        # Manifold assumption
        assert 1 <= mesh.topology().dim() < mesh.geometry().dim()
        gdim = mesh.geometry().dim()

        # Orientation from inside point
        if isinstance(orientation, (list, np.ndarray, tuple)):
            assert len(orientation) == gdim

            kwargs = {'x0%d' % i: val for i, val in enumerate(orientation)}
            orientation = ['x[%d] - x0%d' % (i, i) for i in range(gdim)]
            orientation = df.Expression(orientation, degree=1, **kwargs)

        assert orientation.ufl_shape == (gdim, )

        V = df.VectorFunctionSpace(mesh, 'DG', 0, gdim)
        df.Function.__init__(self, V)
        n_values = self.vector().get_local()

        X = mesh.coordinates()

        dd = X[np.argmin(X[:, 0])] - X[np.argmax(X[:, 0])]

        values = []
        R = np.array([[0, -1], [1, 0]])

        for cell in df.cells(mesh):
            n = cell.cell_normal().array()[:gdim]

            x = cell.midpoint().array()[:gdim]
            # Disagree?
            if np.inner(orientation(x), n) < 0:
                n *= -1.
            values.append(n / np.linalg.norm(n))

        values = np.array(values)

        for sub in range(gdim):
            dofs = V.sub(sub).dofmap().dofs()
            n_values[dofs] = values[:, sub]
        self.vector().set_local(n_values)
        self.vector().apply('insert')