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
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
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)
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
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
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, )