Beispiel #1
0
    def create_measures(self):

        for rom_cell_counter, rom_cell in enumerate(df.cells(
                self._mesh_coarse)):

            form = FluxForm(df.Function(self._V), df.Function(self._Vc))
            facetfct = df.MeshFunction('size_t', self._mesh_fine,
                                       self._mesh_fine.topology().dim() - 1)
            facetfct.set_all(0)

            for local_facet_id, rom_facet in enumerate(df.facets(rom_cell)):
                for fom_facet in df.facets(self._mesh_fine):

                    mp = fom_facet.midpoint()

                    p0 = df.Vertex(self._mesh_coarse, rom_facet.entities(0)[0])
                    p1 = df.Vertex(self._mesh_coarse, rom_facet.entities(0)[1])
                    p0 = df.Point(np.array([p0.x(0), p0.x(1)]))
                    p1 = df.Point(np.array([p1.x(0), p1.x(1)]))

                    eps = mp.distance(p0) + mp.distance(p1) - p0.distance(p1)

                    if eps < 1e-12:

                        facetfct.set_value(fom_facet.index(),
                                           local_facet_id + 1)

                if self._rom_exterior_facets[rom_facet.index()]:
                    form.append_ds(
                        df.Measure('ds',
                                   domain=self._mesh_fine,
                                   subdomain_data=facetfct,
                                   subdomain_id=local_facet_id + 1))
                else:
                    form.append_dS(
                        df.Measure('dS',
                                   domain=self._mesh_fine,
                                   subdomain_data=facetfct,
                                   subdomain_id=local_facet_id + 1))

            cellfct = df.MeshFunction('size_t', self._mesh_fine,
                                      self._mesh_fine.topology().dim())
            cellfct.set_all(0)

            for fom_cell in df.cells(self._mesh_fine):
                if rom_cell.contains(fom_cell.midpoint()):
                    cellfct.set_value(fom_cell.index(), 1)

            form.append_dx(
                df.Measure('dx',
                           domain=self._mesh_fine,
                           subdomain_data=cellfct,
                           subdomain_id=1))
            self._flux_forms.append(form)

        self._initialized = True
Beispiel #2
0
    def compute_parent_facet_indices(submesh, mesh):
        dim = mesh.topology().dim()
        facet_dim = dim - 1
        submesh.init(facet_dim)
        mesh.init(facet_dim)

        # Make sure we have vertex-facet connectivity for parent mesh
        mesh.init(0, facet_dim)

        parent_vertex_indices = submesh.data().array("parent_vertex_indices",
                                                     0)
        # Create the fact map
        parent_facet_indices = np.full(submesh.num_facets(), -1)

        # Iterate over the edges and figure out their parent number
        for local_facet in df.facets(submesh):

            # Get parent indices for edge vertices
            vs = local_facet.entities(0)
            Vs = [df.Vertex(mesh, parent_vertex_indices[int(v)]) for v in vs]

            # Get outgoing facets from the two parent vertices
            facets = [set(V.entities(facet_dim)) for V in Vs]

            # Check intersection
            common_facets = facets[0]
            for f in facets[1:]:
                common_facets = common_facets.intersection(f)
            assert len(common_facets) == 1
            parent_facet_index = list(common_facets)[0]

            # Set value
            parent_facet_indices[local_facet.index()] = parent_facet_index
        return parent_facet_indices
Beispiel #3
0
    def calculate_residual(self, mesh2):
        boundmesh = dolfin.BoundaryMesh(mesh2, "exterior")
        d = max(
            [
                self.bbtree.query(dolfin.Vertex(boundmesh, v_idx).point().array())[0]
                for v_idx in range(boundmesh.num_vertices())
            ]
        )

        return dolfin.MPI.max(mpi_comm_world(), d)
Beispiel #4
0
 def calculate_residual(self, mesh2):
     boundmesh = df.BoundaryMesh(mesh2, "exterior")
     d = max(
         [
             self.bbtree.compute_closest_point(df.Vertex(boundmesh, v_idx).point())[
                 1
             ]
             for v_idx in range(boundmesh.num_vertices())
         ]
     )
     return df.MPI.max(df.mpi_comm_world(), d)
def initial_mesh_morphing(simulation, height_function_cpp, height_function_mean, eps):
    """
    This funcution does the following:

    - Identify the vertices closest to the free surface
    - Get the midpoints between such vertices. This defines a column
      with a startpos and enpos (in x) and a vertex index on the free
      surface.
    - Figure out how to move the free surface vertices to make them
      align with the free surface
    - Morph the mesh to fit the free surface with help from the defined
      columns
    - Return the column definitions for later use in mesh deformations
      as a list of :class:`MeshColumn` objects
    """
    D = simulation.ndim
    assert D == 2

    def get_height_func():
        height = ocellaris_interpolate(
            simulation, height_function_cpp, 'Height function', Vmesh
        )
        height.vector()[:] += height_function_mean
        return height

    mesh = simulation.data['mesh']
    Vmesh = simulation.data['Vmesh']
    Vu = simulation.data['Vu']
    Vc = simulation.data['Vc']
    con_CV = simulation.data['connectivity_CV']

    dofmap = Vmesh.dofmap()
    dofmap_fluid = Vu.dofmap()
    dofmap_colour = Vc.dofmap()
    colour_vec = simulation.data['c'].vector()
    height = get_height_func()

    # Find cells that contain the free surface
    vertices_to_move = set()
    vertex_coords = {}
    vertex_heights = {}
    vertex_dofs = {}
    vertex_fluid_vel_dofs = {}
    for cell in dolfin.cells(mesh):
        cid = cell.index()
        dofs = dofmap.cell_dofs(cid)
        dofs_fluid = dofmap_fluid.cell_dofs(cid)
        vertices = con_CV(cid)
        assert len(dofs) == len(vertices) == 3

        above = []
        below = []
        for i, vid in enumerate(vertices):
            if not vid in vertex_coords:
                vtx = dolfin.Vertex(mesh, vid)
                pos = [vtx.x(d) for d in range(D)]
                dof = dofs[i]
                h = height.vector()[dof][0]
                vertex_coords[vid] = pos
                vertex_heights[vid] = h
                vertex_dofs[vid] = dof
                vertex_fluid_vel_dofs[vid] = dofs_fluid[i]

            # h = vertex_heights[vid]
            h = height_function_mean
            above.append(vertex_coords[vid][1] >= h - 1e6)
            below.append(vertex_coords[vid][1] <= h + 1e6)

        if (all(above) and not any(below)) or (all(below) and not any(above)):
            # The free surface does not cut through this cell
            continue

        # The vertices to move to the free surface location
        # (We will end up moving only the closest vertex in each column)
        vertices_to_move.update(vertices)

    # Find x-positions of the vertices near the free surface
    xpos = [
        (vertex_coords[vid][0], vertex_coords[vid][1], vid) for vid in vertices_to_move
    ]
    assert len(xpos) > 1
    xpos.append((-1e10, None, None))
    xpos.append((1e10, None, None))
    xpos.sort()
    assert xpos[0][2] is None and xpos[-1][2] is None

    # Put the free surface vertices into columns. Make sure the columns
    # have a certain minimum width to be able to gather a few non-free
    # surface vertices in the column and to avoid moving more than one
    # vertex to the same location (in case of them being on the same
    # vertical line)
    columns = []
    in_col = []
    for i in range(1, len(xpos) - 1):
        x = xpos[i][0]
        in_col.append(xpos[i])

        # Get column start and end position
        if len(in_col) == 1:
            startpos = (
                (x + xpos[i - 1][0]) / 2
                if xpos[i - 1][2] is not None
                else x - eps / 100
            )
        endpos = (
            (x + xpos[i + 1][0]) / 2 if xpos[i + 1][2] is not None else x + eps / 100
        )

        # print 'x', x, 'xi-1', xpos[i-1][0], 'xi+1', xpos[i+1][0], 'y',
        # xpos[i][1], 'vid', xpos[i][2]
        if xpos[i + 1][0] - x < eps:
            continue
        # print 'NWCOL'

        # Get the closest y-coordinate (of free surface vertices) in the column
        min_diff_y = (None, None, None, 1e100)
        for p in in_col:
            x, y, vid = p
            dof = vertex_dofs[vid]
            # h = vertex_heights[vid]
            h = height_function_mean
            diff_y = abs(y - h)
            if diff_y < min_diff_y[3]:
                min_diff_y = (x, y, vid, diff_y)
        # print 'FS', min_diff_y

        # Create a MeshColumn object
        vid = min_diff_y[2]
        y_pos = min_diff_y[1]
        fluid_dof = vertex_fluid_vel_dofs[vid]
        col = MeshColumn(startpos, endpos, vid, y_pos, fluid_dof)
        columns.append(col)

        # Reset column
        in_col = []

    assert len(in_col) == 0

    # Put all vertices into columns
    for vid, coords in vertex_coords.items():
        for col in columns:
            if col.start_pos <= coords[0] < col.end_pos:
                col.vertices.append((vid, coords, vertex_dofs[vid]))
                break
        else:
            ocellaris_error(
                'HeightFunctionALE setup error',
                'Vertex at x=%f does not belong to any vertical free surface column'
                % coords[0],
            )

    # Find top and bottomn of each column
    for col in columns:
        miny, maxy = 1e10, -1e10
        for _, coords, _ in col.vertices:
            miny = min(coords[1], miny)
            maxy = max(coords[1], maxy)
        col.top = maxy
        col.bottom = miny

    ##############################################

    # Find the velocity with which to move the mesh to align it with the free surface
    vels = []
    for col in columns:
        vid = col.free_surface_vertex
        h = vertex_heights[vid]
        y = vertex_coords[vid][1]
        vels.append(h - y)

    # Move the mesh
    old_dt = simulation.dt
    simulation.dt = 1.0
    morph_mesh(simulation, columns, vels)
    simulation.dt = old_dt

    # Reset the mesh velocities
    for d in range(simulation.ndim):
        simulation.data['u_mesh%d' % d].vector().zero()

    ##############################################

    # Initialize the colour field. This will not change during the simulation.
    # Wet cells will remain wet and vice versa
    height = get_height_func()
    for cell in dolfin.cells(mesh):
        cid = cell.index()
        dofs = dofmap.cell_dofs(cid)
        h = sum(height.vector()[dof][0] for dof in dofs) / len(dofs)
        y = cell.midpoint().y()

        dofs_colour = dofmap_colour.cell_dofs(cid)
        assert len(dofs_colour) == 1
        dof_colour = dofs_colour[0]
        if y > h:
            colour_vec[dof_colour] = 0.0
        else:
            colour_vec[dof_colour] = 1.0

    return columns
Beispiel #6
0
    def pbc_facet_function(part_vectors,
                           mesh,
                           facet_function,
                           per_choice: dict,
                           dim=2,
                           tol=GEO_TOLERANCE):
        """[summary]

        Parameters
        ----------
        part_vectors : np.array
        mesh : Mesh
        facet_function : MeshFunction
        per_choice : dict
            key can be : 'X', 'Y'
            values : tuple (value of facetfunction for master, value for slave)
            Ex : {'X' : (3,5)}
        tol : float, optional

        Returns
        -------
        PeriodicDomain
        """

        # ! Not tested yet
        basis = list()
        for i in range(np.size(part_vectors, 1)):
            basis.append(fe.as_vector(part_vectors[:, i]))
        per_values = [val for couple in per_choice for val in couple]
        coordinates = dict()
        mesh.init(1,
                  0)  # Compute connectivity between given pair of dimensions.
        for val in per_values:
            points_for_val = list()
            facet_idces = facet_function.where_equal(val)
            for i in facet_idces:
                vertices_idces = fe.Facet(mesh, i).entities(0)
                for j in vertices_idces:
                    coord = fe.Vertex(mesh, j).point().array()
                    points_for_val.append(coord)
            coordinates[val] = points_for_val
        master_tests, slave_tests, per_vectors = list(), list(), list()
        for key, (master_idx, slave_idx) in per_choice.items():

            def master_test(x):
                return any(
                    np.allclose(x, pt, atol=tol)
                    for pt in coordinates[master_idx])

            def slave_test(x):
                return any(
                    np.allclose(x, pt, atol=tol)
                    for pt in coordinates[slave_idx])

            master_tests.append(master_test)
            slave_tests.append(slave_test)
            if key.lower() == "x":
                per_vectors.append(basis[0])
            elif key.lower() == "y":
                per_vectors.append(basis[1])

        return PeriodicDomain(per_vectors, master_tests, slave_tests, dim, tol)
def extractFeNiCsBiVFacet(ugrid, geometry="BiV"):

    tol = 1e-2

    #ugrid = vtk_py.readUGrid(meshfilename)

    # Extract surface
    geom = vtk.vtkGeometryFilter()
    if (vtk.vtkVersion().GetVTKMajorVersion() < 6):
        geom.SetInput(ugrid)
    else:
        geom.SetInputData(ugrid)
    geom.Update()
    surf = geom.GetOutput()

    bc_pts_locator = []
    bc_pts = []
    bc_pts_range = []
    bc_pts_map = []

    # Extract Surface Normal
    normal = vtk.vtkPolyDataNormals()
    if (vtk.vtkVersion().GetVTKMajorVersion() < 6):
        normal.SetInput(surf)
    else:
        normal.SetInputData(surf)
    normal.ComputeCellNormalsOn()
    normal.Update()
    surf_w_norm = normal.GetOutput()

    #vtk_py.writePData(normal.GetOutput(), "normal.vtk")

    zmax = surf_w_norm.GetBounds()[5]

    surf_w_norm.BuildLinks()
    idlist = vtk.vtkIdList()
    basecellidlist = vtk.vtkIdTypeArray()
    basesurf = vtk.vtkPolyData()
    for p in range(0, surf_w_norm.GetNumberOfCells()):
        zvec = surf_w_norm.GetCellData().GetNormals().GetTuple3(p)[2]

        surf_w_norm.GetCellPoints(p, idlist)
        zpos = surf_w_norm.GetPoints().GetPoint(idlist.GetId(0))[2]

        if ((abs(zvec - 1.0) < tol or abs(zvec + 1.0) < tol)
                and (abs(zmax - zpos) < tol)):
            surf_w_norm.DeleteCell(p)
            basecellidlist.InsertNextValue(p)

    basesurf = vtk_py.extractCellFromPData(basecellidlist, surf)
    baseptlocator = vtk.vtkPointLocator()
    baseptlocator.SetDataSet(basesurf)
    baseptlocator.BuildLocator()

    #######################################################################

    surf_w_norm.RemoveDeletedCells()

    cleanpdata = vtk.vtkCleanPolyData()
    if (vtk.vtkVersion().GetVTKMajorVersion() < 6):
        cleanpdata.SetInput(surf_w_norm)
    else:
        cleanpdata.SetInputData(surf_w_norm)
    cleanpdata.Update()

    connfilter = vtk.vtkPolyDataConnectivityFilter()
    if (vtk.vtkVersion().GetVTKMajorVersion() < 6):
        connfilter.SetInput(cleanpdata.GetOutput())
    else:
        connfilter.SetInputData(cleanpdata.GetOutput())
    connfilter.Update()

    print "Total_num_points = ", cleanpdata.GetOutput().GetNumberOfPoints()
    tpt = 0

    if (geometry == "BiV"):
        nsurf = 3
    else:
        nsurf = 2

    for p in range(0, nsurf):

        pts = vtk.vtkPolyData()

        connfilter.SetExtractionModeToSpecifiedRegions()
        [connfilter.DeleteSpecifiedRegion(k) for k in range(0, nsurf)]
        connfilter.AddSpecifiedRegion(p)
        connfilter.ScalarConnectivityOff()
        connfilter.FullScalarConnectivityOff()
        connfilter.Update()

        cleanpdata2 = vtk.vtkCleanPolyData()
        if (vtk.vtkVersion().GetVTKMajorVersion() < 6):
            cleanpdata2.SetInput(connfilter.GetOutput())
        else:
            cleanpdata2.SetInputData(connfilter.GetOutput())
        cleanpdata2.Update()

        pts.DeepCopy(cleanpdata2.GetOutput())

        tpt = tpt + cleanpdata2.GetOutput().GetNumberOfPoints()

        ptlocator = vtk.vtkPointLocator()
        ptlocator.SetDataSet(pts)
        ptlocator.BuildLocator()

        bc_pts_locator.append(ptlocator)
        bc_pts.append(pts)
        bc_pts_range.append([
            abs(pts.GetBounds()[k + 1] - pts.GetBounds()[k])
            for k in range(0, 6, 2)
        ])

    #vtk_py.writePData(connfilter.GetOutput(), "/home/likchuan/Research/fenicsheartmesh/ellipsoidal/Geometry/test.vtk")

    print "Total_num_points = ", tpt

    Epiid = np.argmax(np.array([max(pts) for pts in bc_pts_range]))
    maxzrank = np.array([pts[2] for pts in bc_pts_range]).argsort()

    if (geometry == "BiV"):
        LVid = maxzrank[1]
        RVid = 3 - (LVid + Epiid)
        bc_pts_map = [4, 4, 4, 4]
        bc_pts_map[Epiid] = 1
        bc_pts_map[LVid] = 2
        bc_pts_map[RVid] = 3
        baseid = 3
    else:
        LVid = maxzrank[0]
        bc_pts_map = [4, 4, 4]
        bc_pts_map[Epiid] = 1
        bc_pts_map[LVid] = 2
        baseid = 2

    bc_pts_locator.append(baseptlocator)
    bc_pts.append(basesurf)

    dolfin_mesh = vtk_py.convertUGridToXMLMesh(ugrid)
    dolfin_facets = dolfin.FacetFunction('size_t', dolfin_mesh)
    dolfin_facets.set_all(0)

    for facet in dolfin.SubsetIterator(dolfin_facets, 0):
        for locator in range(0, nsurf + 1):
            cnt = 0
            for p in range(0, 3):
                v0 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(0)
                v1 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(1)
                v2 = dolfin.Vertex(dolfin_mesh, facet.entities(0)[p]).x(2)
                ptid = bc_pts_locator[locator].FindClosestPoint(v0, v1, v2)
                x0 = bc_pts[locator].GetPoints().GetPoint(ptid)
                dist = vtk.vtkMath.Distance2BetweenPoints([v0, v1, v2], x0)
                if (dist < 1e-5):
                    cnt = cnt + 1
            if (cnt == 3):
                dolfin_facets[facet] = bc_pts_map[locator]

    dolfin_edges = dolfin.EdgeFunction('size_t', dolfin_mesh)
    dolfin_edges.set_all(0)

    epilocator = Epiid
    lvendolocator = LVid

    for edge in dolfin.SubsetIterator(dolfin_edges, 0):
        cnt_epi = 0
        cnt_lvendo = 0
        for p in range(0, 2):
            v0 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(0)
            v1 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(1)
            v2 = dolfin.Vertex(dolfin_mesh, edge.entities(0)[p]).x(2)

            epiptid = bc_pts_locator[epilocator].FindClosestPoint(v0, v1, v2)
            epix0 = bc_pts[epilocator].GetPoints().GetPoint(epiptid)
            epidist = vtk.vtkMath.Distance2BetweenPoints([v0, v1, v2], epix0)

            topptid = bc_pts_locator[baseid].FindClosestPoint(v0, v1, v2)
            topx0 = bc_pts[baseid].GetPoints().GetPoint(topptid)
            topdist = vtk.vtkMath.Distance2BetweenPoints([v0, v1, v2], topx0)

            lvendoptid = bc_pts_locator[lvendolocator].FindClosestPoint(
                v0, v1, v2)
            lvendox0 = bc_pts[lvendolocator].GetPoints().GetPoint(lvendoptid)
            lvendodist = vtk.vtkMath.Distance2BetweenPoints([v0, v1, v2],
                                                            lvendox0)

            if (topdist < 1e-5 and epidist < 1e-5):
                cnt_epi = cnt_epi + 1

            if (topdist < 1e-5 and lvendodist < 1e-5):
                cnt_lvendo = cnt_lvendo + 1

            if (cnt_epi == 2):
                dolfin_edges[edge] = 1

            if (cnt_lvendo == 2):
                dolfin_edges[edge] = 2

    return dolfin_mesh, dolfin_facets, dolfin_edges
Beispiel #8
0
    def find_mesh_info(self):
        coords = self.mesh.coordinates()
        self.length = len(coords)
        max_v = coords.max(axis=0)
        min_v = coords.min(axis=0)

        self.xmin = min_v[0]
        self.xmax = max_v[0]
        self.ymin = min_v[1]
        self.ymax = max_v[1]

        self.width = self.xmax - self.xmin
        self.height = self.ymax - self.ymin

        self.dim = self.mesh.topology().dim()

        # Collect all vertices that lie on one of the periodic
        # boundaries of the mesh.
        px_mins = []
        px_maxs = []
        py_mins = []
        py_maxs = []
        mesh = self.mesh
        for vertex in df.vertices(mesh):
            if vertex.point().x() == self.xmin:
                px_mins.append(df.Vertex(mesh, vertex.index()))
            elif vertex.point().x() == self.xmax:
                px_maxs.append(df.Vertex(mesh, vertex.index()))

            if vertex.point().y() == self.ymin:
                py_mins.append(df.Vertex(mesh, vertex.index()))
            elif vertex.point().y() == self.ymax:
                py_maxs.append(df.Vertex(mesh, vertex.index()))

        # Collect the indices of vertices on the 'min' boundary
        # and find all vertices on the 'max' boundary which match
        # one of those 'min' vertices.
        indics = []
        indics_pbc = []

        for v1 in px_mins:
            indics.append(v1.index())
            for v2 in px_maxs:
                if v1.point().y() == v2.point().y() and v1.point().z(
                ) == v2.point().z():
                    indics_pbc.append(v2.index())
                    px_maxs.remove(v2)

        for v1 in py_mins:
            indics.append(v1.index())
            for v2 in py_maxs:
                if v1.point().x() == v2.point().x() and v1.point().z(
                ) == v2.point().z():
                    indics_pbc.append(v2.index())
                    py_maxs.remove(v2)
        """
        print self.xmin,self.xmax,self.ymin,self.ymax,self.height,self.width
        print '='*100
        print indics,indics_pbc
        """
        ids = np.array(indics, dtype=np.int32)
        ids_pbc = np.array(indics_pbc, dtype=np.int32)

        #assert len(indics) == len(indics_pbc)

        self.ids = np.array(
            [ids[:], ids[:] + self.length, ids[:] + self.length * 2],
            dtype=np.int32)
        self.ids_pbc = np.array([
            ids_pbc[:], ids_pbc[:] + self.length, ids_pbc[:] + self.length * 2
        ],
                                dtype=np.int32)

        self.ids.shape = (-1, )
        self.ids_pbc.shape = (-1, )