def initial_mesh(self):

        self.initial_hot_wall_refinement_cycles = 8

        mesh = self.coarse_mesh()

        for i in range(self.initial_hot_wall_refinement_cycles):

            cell_markers = fenics.MeshFunction("bool", mesh,
                                               mesh.topology().dim(), False)

            cell_markers.set_all(False)

            for cell in fenics.cells(mesh):

                found_left_boundary = False

                for vertex in fenics.vertices(cell):

                    if fenics.near(vertex.x(0), 0.):

                        found_left_boundary = True

                        break

                if found_left_boundary:

                    cell_markers[cell] = True

                    break  # There should only be one such point in 1D.

            mesh = fenics.refine(mesh, cell_markers)

        return mesh
    def refine_initial_mesh(self):
        """ Replace 2D refinement method with 3D method. Perhaps one could make an n-dimensional method. """
        for i in range(self.initial_hot_wall_refinement_cycles):

            cell_markers = fenics.MeshFunction("bool", self.mesh,
                                               self.mesh.topology().dim(),
                                               False)

            for cell in fenics.cells(self.mesh):

                found_left_boundary = False

                for vertex in fenics.vertices(cell):

                    if fenics.near(vertex.x(0), 0.):

                        found_left_boundary = True

                        break

                if found_left_boundary:

                    cell_markers[cell] = True

            self.mesh = fenics.refine(self.mesh, cell_markers)
예제 #3
0
def refine_near_left_boundary(mesh, cycles):
    """ Refine mesh near the left boundary.
    The usual approach of using SubDomain and EdgeFunction isn't appearing to work
    in 1D, so I'm going to just loop through the cells of the mesh and set markers manually.
    """
    for i in range(cycles):

        cell_markers = fenics.CellFunction("bool", mesh)

        cell_markers.set_all(False)

        for cell in fenics.cells(mesh):

            found_left_boundary = False

            for vertex in fenics.vertices(cell):

                if fenics.near(vertex.x(0), 0.):

                    found_left_boundary = True

            if found_left_boundary:

                cell_markers[cell] = True

                break  # There should only be one such point.

        mesh = fenics.refine(mesh, cell_markers)

    return mesh
예제 #4
0
파일: utils.py 프로젝트: bdevl/PGMCPC
    def _assemble(self):

        coordinates = np.array(np.zeros(self.mesh.num_vertices()),
                               dtype=[('x', float), ('y', float)])
        for i, vertex in enumerate(df.vertices(self.mesh)):
            coordinates['x'][i] = vertex.x(0)
            coordinates['y'][i] = vertex.x(1)

        self._Ny = len(np.unique(coordinates['y']))
        self._Nx = len(np.unique(coordinates['x']))

        coordinates = np.sort(coordinates, order=['y', 'x'])

        X = coordinates['x'].reshape(self._Ny, self._Nx)
        Y = coordinates['y'].reshape(self._Ny, self._Nx)

        self._X = np.flipud(X)
        self._Y = np.flipud(Y)

        # check if uniform mesh
        T = np.diff(X, axis=1)
        self._dx = T[0, 0]
        assert (np.all(np.abs(T - self._dx) < 1e-12))
        T = np.diff(Y, axis=0)
        self._dy = T[0, 0]
        assert (np.all(np.abs(T - self._dy) < 1e-12))

        Interpolator = np.zeros(
            ((self._Ny - 1) * (self._Nx - 1), self.V.dim()))

        for i, cell in enumerate(df.cells(self.mesh)):

            x = cell.midpoint().x()
            y = cell.midpoint().y()

            cx = int(x // self._dx)
            cy = int(y // self._dy)

            cy = (self._Ny - 2) - cy
            pixel_id = cy * (self._Ny - 1) + cx

            Interpolator[pixel_id, i] = 0.5

        ReverseInterpolator = np.zeros(
            (self.V.dim(), (self._Ny - 1) * (self._Nx - 1)))

        for i, row in enumerate(Interpolator):
            ind = np.where(row)[0]
            ReverseInterpolator[ind[0], i] = 1
            ReverseInterpolator[ind[1], i] = 1

        self.Interpolator = Interpolator
        self.ReverseInterpolator = ReverseInterpolator

        #
        a, b = np.where(self.Interpolator != 0)
        self._DofToPixelPermutator = torch.tensor(b, dtype=torch.long)

        a, b = self.ReverseInterpolator.nonzero()
        self._PixelToDofPermutator = torch.tensor(b, dtype=torch.long)
예제 #5
0
 def system_multiplication_DoGIP(AT_dogip, Bhat, u_vec):
     # mutliplication with DoGIP decomposition
     Au = np.zeros_like(u_vec)
     for ii, cell in enumerate(cells(mesh)):
         ind = dofmapV.cell_dofs(ii)  # local to global map
         Au[ind] += Bhat.T.dot(AT_dogip[ii] * Bhat.dot(u_vec[ind]))
     return Au
    def refine_initial_mesh(self):
        """ Locally refine near the hot boundary """
        for i in range(self.initial_hot_boundary_refinement_cycles):

            cell_markers = fenics.MeshFunction("bool", self.mesh,
                                               self.mesh.topology().dim(),
                                               False)

            cell_markers.set_all(False)

            for cell in fenics.cells(self.mesh):

                found_left_boundary = False

                for vertex in fenics.vertices(cell):

                    if fenics.near(vertex.x(0), 0.):

                        found_left_boundary = True

                        break

                if found_left_boundary:

                    cell_markers[cell] = True

                    break  # There should only be one such point in 1D.

            self.mesh = fenics.refine(
                self.mesh, cell_markers)  # Does this break references?
def local_refine(mesh, center, r):
    xc, yc = center
    cell_markers = MeshFunction("bool", mesh, mesh.topology().dim())
    for c in cells(mesh):
        mp = c.midpoint()
        cell_markers[c] = sqrt((mp[0] - xc) * (mp[0] - xc) + (mp[1] - yc) *
                               (mp[1] - yc)) < r
    mesh = refine(mesh, cell_markers)
    return mesh
예제 #8
0
    def build_mesh(self):
        self.length = 8.
        self.height = 2.
        self.notch_length = 0.2
        self.notch_height = 0.4

        domain = mshr.Polygon([fe.Point(0., 0.), 
                  fe.Point(self.length/2. - self.notch_length/2., 0.),
                  fe.Point(self.length/2., self.notch_height),
                  fe.Point(self.length/2. + self.notch_length/2., 0.),
                  fe.Point(self.length, 0.),
                  fe.Point(self.length, self.height),
                  fe.Point(self.length/2. + self.notch_length/2., self.height),
                  fe.Point(self.length/2., self.height),
                  fe.Point(self.length/2. - self.notch_length/2., self.height),
                  fe.Point(0., self.height)])

        # resolution = 100 if self.local_refinement_iteration == 0 else 200
        # self.mesh = mshr.generate_mesh(domain, resolution)

        self.mesh = mshr.generate_mesh(domain, 100)
        for i in range(self.local_refinement_iteration):
            cell_markers = fe.MeshFunction('bool', self.mesh, self.mesh.topology().dim())
            cell_markers.set_all(False)
            for cell in fe.cells(self.mesh):
                p = cell.midpoint()
                if  p[0] > 14./32.*self.length and p[0] < 18./32.*self.length and p[1] < self.height - self.notch_height:
                    cell_markers[cell] = True
            self.mesh = fe.refine(self.mesh, cell_markers)

        length = self.length
        height = self.height
        notch_length = self.notch_length

        class Upper(fe.SubDomain):
            def inside(self, x, on_boundary):
                # return on_boundary
                return on_boundary and fe.near(x[1], height) 


        class LeftCorner(fe.SubDomain):
            def inside(self, x, on_boundary):
                return fe.near(x[0], 0.) and fe.near(x[1], 0.)

        class RightCorner(fe.SubDomain):
            def inside(self, x, on_boundary):
                return fe.near(x[0], length) and fe.near(x[1], 0.)

        class MiddlePoint(fe.SubDomain):
            def inside(self, x, on_boundary):                    
                # return fe.near(x[0], length/2.) and fe.near(x[1], height)
                return x[0] > length/2. - notch_length/2.  and  x[0] < length/2. + notch_length/2. and fe.near(x[1], height)

        self.upper = Upper()
        self.left = LeftCorner()
        self.right = RightCorner()
        self.middle = MiddlePoint()
예제 #9
0
def adapt_coarse_solution_to_fine_solution(scalar,
                                           coarse_solution,
                                           fine_solution,
                                           element,
                                           absolute_tolerance=1.e-2,
                                           maximum_refinement_cycles=6,
                                           circumradius_threshold=0.01):
    """ Refine the mesh of the coarse solution until the interpolation error tolerance is met. """
    adapted_coarse_mesh = fenics.Mesh(coarse_solution.function_space().mesh())

    adapted_coarse_function_space = fenics.FunctionSpace(
        adapted_coarse_mesh, element)

    adapted_coarse_solution = fenics.Function(adapted_coarse_function_space)

    adapted_coarse_solution.leaf_node().vector(
    )[:] = coarse_solution.leaf_node().vector()

    for refinement_cycle in range(maximum_refinement_cycles):

        cell_markers = fenics.MeshFunction(
            "bool", adapted_coarse_mesh.leaf_node(),
            adapted_coarse_mesh.topology().dim(), False)

        for coarse_cell in fenics.cells(adapted_coarse_mesh.leaf_node()):

            coarse_value = scalar(adapted_coarse_solution.leaf_node(),
                                  coarse_cell.midpoint())

            fine_value = scalar(fine_solution.leaf_node(),
                                coarse_cell.midpoint())

            if (abs(coarse_value - fine_value) > absolute_tolerance):

                cell_markers[coarse_cell] = True

        cell_markers = unmark_cells_below_circumradius(
            adapted_coarse_mesh.leaf_node(), cell_markers,
            circumradius_threshold)

        if any(cell_markers):

            adapted_coarse_mesh = fenics.refine(adapted_coarse_mesh,
                                                cell_markers)

            adapted_coarse_function_space = fenics.FunctionSpace(
                adapted_coarse_mesh, element)

            adapted_coarse_solution = fenics.project(
                fine_solution.leaf_node(),
                adapted_coarse_function_space.leaf_node())

        else:

            break

    return adapted_coarse_solution, adapted_coarse_function_space, adapted_coarse_mesh
예제 #10
0
    def coarsen(self):
        """ Remesh and refine the new mesh until the interpolation error tolerance is met. 
    
        For simplicity, for now we'll consider only one scalar component of the solution.
        """
        time = 0. + self.old_state.time

        fine_solution = self.state.solution.copy(deepcopy=True)

        self.setup_coarse_mesh()

        for refinement_cycle in range(
                self.coarsening_maximum_refinement_cycles):

            self.setup_function_space()

            self.setup_states()

            self.old_state.time = 0. + time

            self.old_state.solution = fenics.project(
                fine_solution.leaf_node(), self.function_space.leaf_node())

            if refinement_cycle == self.coarsening_maximum_refinement_cycles:

                break

            exceeds_tolerance = fenics.MeshFunction("bool",
                                                    self.mesh.leaf_node(),
                                                    self.mesh.topology().dim(),
                                                    False)

            exceeds_tolerance.set_all(False)

            for cell in fenics.cells(self.mesh.leaf_node()):

                coarse_value = self.old_state.solution.leaf_node()(cell.midpoint())\
                    [self.coarsening_scalar_solution_component_index]

                fine_value = fine_solution.leaf_node()(cell.midpoint())\
                    [self.coarsening_scalar_solution_component_index]

                if (abs(coarse_value - fine_value) >
                        self.coarsening_absolute_tolerance):

                    exceeds_tolerance[cell] = True

            if any(exceeds_tolerance):

                self.mesh = fenics.refine(self.mesh, exceeds_tolerance)

            else:

                break

        self.setup_problem_and_solver()  # We broke important references.
예제 #11
0
def get_A_T(m, V, W=None, problem=1):
    """
    The element-wise (local) system matrices of DoGIP
    Projection/interpolation operator between spaces V and W on the whole computational domain.

    Parameters
    ----------
    m : Expression
        defines material coefficients as a scalar valued function (without loss of generality,
        material m is considered to be isotropic)
    V : FunctionSpace
        original finite element space
    W : FunctionSpace
        double-grid finite element space
    problem : {int, string}
        parameter defining problem: 0 - weighted projection, 1 - elliptic problem

    Returns
    -------
    AT_dogip : ndarray
        element-wise (local) system matrices of DoGIP
    """
    mesh = V.mesh()
    dim = mesh.geometry().dim()

    w = TestFunction(W)
    if problem in [0, 'projection']:
        AT_dogip = np.empty([mesh.num_cells(), W.element().space_dimension()])
        for ii, cell in enumerate(cells(V.mesh())):
            AT_dogip[ii] = assemble_local(m * w * dx, cell)
    elif problem in [1, 'elliptic']:
        # assumes (without generality) that material coefficients are isotropic
        AT_dogip = np.empty(
            [mesh.num_cells(), dim, dim,
             W.element().space_dimension()])
        for ii, cell in enumerate(cells(V.mesh())):
            refmap = Mapping(nodes=np.array(
                cell.get_vertex_coordinates()).reshape(dim + 1, dim))
            MT = np.einsum('ij,k', np.eye(dim),
                           np.atleast_1d(assemble_local(m * w * dx, cell)))
            AT_dogip[ii] = np.einsum('rp,sq,pqj->rsj', refmap.Ai, refmap.Ai,
                                     MT)
    return AT_dogip
예제 #12
0
def plot_mesh(mesh, color="green", alpha=0.5):
    """ Plot 2D mesh."""
    coors = mesh.coordinates()
    trigs = numpy.asarray([cell.entities(0) for cell in cells(mesh)])
    trimesh = tri.Triangulation(coors[:, 0], coors[:, 1], trigs)
    plt.triplot(trimesh, color=color, alpha=alpha)
    (x0, y0) = numpy.min(mesh.coordinates(), axis=0)
    (x1, y1) = numpy.max(mesh.coordinates(), axis=0)
    plt.axis([x0, x1, y0, y1])
    plt.axes().set_aspect('equal')
    def refine_mesh(self, tolerance: float) -> Optional[bool]:
        """Generate refined mesh.

        This method locates cells of the mesh where the error of the
        eigenfunction is above a certain threshold and generates a new mesh
        with finer resolution on the problematic regions.

        For a given eigenfunction $u$ with corresponding eigenvalue
        $\lambda$, it must be true that $a(u, v) = \lambda b(u, v)$ for all
        functions $v$. We make $v$ go through all the basis functions on the
        mesh and locate the cells where the previous identity fails to hold.

        Parameters
        ----------
        tolerance : float
            Criterion to determine whether a cell needs to be refined or not.

        Returns
        -------
        refined_mesh : Optional[fenics.Mesh]
            A new mesh derived from `mesh` with higher level of granularity
            on certain regions. If no refinements are needed, None is
            returned.

        """
        ew, ev = self.eigenvalues[1:], self.eigenfunctions[1:]
        dofs_needing_refinement = set()

        # Find all the degrees of freedom needing refinement.
        for k, (l, u) in enumerate(zip(ew, ev)):
            v = fenics.TrialFunction(self.vector_space)
            a, b = self._construct_eigenproblem(u, v)
            A = fenics.assemble(a * fenics.dx)
            B = fenics.assemble(b * fenics.dx)

            error = np.abs((A - l * B).sum())
            indices = np.flatnonzero(error > tolerance)
            dofs_needing_refinement.update(indices)

        if not dofs_needing_refinement:
            return

        # Refine the cells corresponding to the degrees of freedom needing
        # refinement.
        dofmap = self.vector_space.dofmap()
        cell_markers = fenics.MeshFunction('bool', self.mesh,
                                           self.mesh.topology().dim())
        cell_markers.set_all(False)
        for cell in fenics.cells(self.mesh):
            cell_dofs = set(dofmap.cell_dofs(cell.index()))
            if cell_dofs.intersection(dofs_needing_refinement):
                cell_markers[cell] = True

        return fenics.refine(self.mesh, cell_markers)
예제 #14
0
파일: utils.py 프로젝트: bdevl/PGMCPC
def AssembleMeshOverlapMatrix(Vc, Vf):

    # assumes that Vc and Vf are conforming function spaces
    meshc = Vc.mesh()
    meshf = Vf.mesh()

    if Vc.dim() != meshc.num_cells() or Vf.dim() != meshf.num_cells():
        raise TypeError('One of supplied function spaces not of type DG0')

    if meshc.num_cells() > meshf.num_cells():
        raise ValueError

    tree = meshc.bounding_box_tree()

    reversemap = np.zeros(meshf.num_cells(), dtype=np.int)
    areafraction = np.zeros(meshf.num_cells())
    coarse_area_by_id = np.zeros(meshc.num_cells())

    dofmapc = Vc.dofmap()
    dofmapf = Vf.dofmap()

    for cell in df.cells(meshc):
        coarse_area_by_id[cell.index()] = cell.volume()

    for cell in df.cells(meshf):
        cell_id = tree.compute_first_entity_collision(cell.midpoint())
        coarse_dof = dofmapc.cell_dofs(cell_id)
        fine_dof = dofmapf.cell_dofs(cell.index())
        reversemap[fine_dof] = coarse_dof
        areafraction[fine_dof] = cell.volume() / coarse_area_by_id[cell_id]

    _W = np.zeros((Vc.dim(), Vf.dim()))

    #  Issue: slow and not sparse
    for i in range(Vc.dim()):
        finedofs = np.where(reversemap == i)[0]
        _W[i, finedofs] = areafraction[finedofs]

    W = csr_matrix(_W); del(_W);
    return W
예제 #15
0
def unmark_cells_below_circumradius(mesh, cell_markers, circumradius):

    for cell in fenics.cells(mesh):

        if not cell_markers[cell]:

            continue

        if cell.circumradius() <= circumradius:

            cell_markers[cell] = False

    return cell_markers
예제 #16
0
            ver = fn.Vertex(mesh, node)
            for edge in fn.edges(ver):
                if edge.index() in BoundaryEdges:
                    entity = edge.entities(0)
                    if all(item in nodes for item in entity):
                        boundaries[edge.index()] = idx
        idx += 1
    else:
        interior[key] = nodes

sections = fn.MeshFunction('size_t', mesh, dim=2)
sections.set_all(0)
for num, (key, value) in enumerate(Faces.items(), 1):
    for node in value:
        ver = fn.Vertex(mesh, node)
        for cell in fn.cells(ver):
            entity = cell.entities(0)
            if all(item in value for item in entity):
                sections[cell.index()] = num

fn.File("./UserFiles/boundaries.pvd") << boundaries
fn.File("./UserFiles/sections.pvd") << sections

F = fn.Function(V)
File = fn.File("./UserFiles/result.pvd")
for i in range(10):
    t = 0 + (i + 1) / 10
    F.interpolate(fn.Expression("x[0]+5*t*x[1]", t=t, degree=2))
    File << (F, t)
''' changes made: 
예제 #17
0
import matplotlib.pyplot as plt
from fenics import FunctionSpace, cells, interpolate
from regge_geodesics import exponential_map
from utils import plot_mesh, reference_data, exact_kepler

# get initial data and mesh for a Kelper problem with
# energy H=-1.5 (elliptic orbit) and initial momentum L=0.5.
H = -1.5
L = 0.5
(_, _, gexp, mesh) = reference_data(H=H,
                                    L=L,
                                    mesh_type='unstructured',
                                    mesh_size=24,
                                    padding=0.07)
(q0, p0, T, S, (c, a, b), sol, t2s) = exact_kepler(H, L)

# Regge 0 is used
g = interpolate(gexp, FunctionSpace(mesh, "Regge", 1))
# ODE solver step size
h = min([c.inradius() for c in cells(mesh)]) / 2.0
# solve
(ts, solh) = exponential_map(g, 0, q0, p0, h, 50 * S)
# plot
(qh, _) = solh(ts)
plt.plot(qh[:, 0], qh[:, 1], color="blue")
plot_mesh(mesh)
plt.show()
예제 #18
0
def mfd_cellcell(mesh, V, u_n, De, nexp):
    """
    MFD cell-to-cell
    Flow routing distributed from cell-to-cell

    :param mesh: mesh object generated using mshr (fenics)
    :param V: finite element function space
    :param u_n: solution (trial function) for water flux
    :param De: dimensionless diffusion coefficient
    :param nexp: water flux exponent
    :return:
    """

    # get a map of neighbours (thanks google!)
    tdim = mesh.topology().dim()
    mesh.init(tdim - 1, tdim)
    cell_neighbors = np.array([
        sum((list(filter(lambda ci: ci != cell.index(), facet.entities(tdim)))
             for facet in facets(cell)), []) for cell in cells(mesh)
    ])

    # first get the elevation area of each element
    dofmap = V.dofmap()
    elevation = []
    area = []
    xm = []
    ym = []
    for cell in cells(mesh):
        cellnodes = dofmap.cell_dofs(cell.index())
        elevation.append(sum(u_n.vector()[cellnodes]) / 3)
        area.append(cell.volume())
        p = cell.midpoint()
        xm.append(p.x())
        ym.append(p.y())
    elevation = np.array(elevation)
    area = np.array(area)
    xm = np.array(xm)
    ym = np.array(ym)

    # now sort the vector of elevations by decending topography
    ind = np.argsort(-elevation)
    sorted_neighbors = cell_neighbors[ind]

    # determine length between elements
    steep_len = []
    for cell in cells(mesh):
        xh = xm[cell.index()]
        yh = ym[cell.index()]

        neicells = cell_neighbors[cell.index()]
        tnei = elevation[neicells]
        imin = np.argmin(tnei)
        ncell = neicells[imin]
        xn = xm[ncell]
        yn = ym[ncell]

        steep_len.append(np.sqrt((xh - xn) * (xh - xn) + (yh - yn) *
                                 (yh - yn)))
    steep_len = np.array(steep_len)

    flux = area / steep_len

    # determine flux from highest to lowest cells
    for cell in cells(mesh):
        neicells = sorted_neighbors[cell.index()]
        tnei = elevation[neicells]
        imin = np.argmin(tnei)
        ncell = neicells[imin]

        weight = np.zeros(len(neicells))
        i = 0
        for neicell in neicells:
            weight[i] = elevation[ind[cell.index()]] - elevation[neicell]
            # downhill only
            if weight[i] < 0:
                weight[i] = 0
            i += 1

        # weight flux by the sum of the lengths down slope
        if max(weight) > 0:
            weight = weight / sum(weight)
        else:
            weight[:] = 0
        i = 0
        for neicell in neicells:
            flux[neicell] = flux[neicell] + flux[ind[cell.index()]] * weight[i]
            i += 1

    # interpolate to the nodes
    gc = mesh.coordinates()

    flux_node = np.zeros(len(gc))
    for cell in cells(mesh):
        cellnodes = dofmap.cell_dofs(cell.index())
        for nod in cellnodes:
            flux_node[nod] = flux_node[nod] + flux[cell.index()] / 3

    q = Function(V)
    q.vector()[:] = 1 + De * pow(flux_node, nexp)

    return q
# initialize
degree = int(sys.argv[1])
levels = [int(sys.argv[2]) * 2**i for i in range(int(sys.argv[3]))]
(q0, p0, T, S, (c, a, b), sol, t2s) = exact_kepler(H, L)
Tmax = T * M
gexp = kepler_jacobi_metric(c=H)
ee = []
eH = []
eL = []
hs = []

# main loop
for n in levels:
    (_, _, _, mesh) = reference_data(H, L, 'unstructured', n, padding=padding)
    hs.append(numpy.mean([c.h() for c in cells(mesh)]))

    print('Compute the solution for n={}...'.format(n))
    g = interpolate(gexp, FunctionSpace(mesh, 'Regge', degree))
    h = min([c.inradius() for c in cells(mesh)]) / 2.0

    (_, solh) = exponential_map(g, 0, q0, p0, h, t2s(Tmax), verbose=True)

    print('Evaluate the solution and compute the error...')
    t = numpy.linspace(0, Tmax, 200 * M + 1)
    s = t2s(t)
    qe = sol(t)
    (qh, ph) = solh(s)
    (Hh, Lh) = integrals(qh, ph)
    d = qe - qh
    ee.append(numpy.max(numpy.sqrt(numpy.array([q.dot(q) for q in d]))))