def load_microstructure(h5file, fgroup, mesh, geo, include_sheets=True): if h5file.has_dataset(fgroup): # Get fibers fiber_attrs = h5file.attributes(fgroup) fspace = fiber_attrs["space"] if fspace is None: # Assume quadrature 4 family = "Quadrature" order = 4 else: family, order = fspace.split("_") namesstr = fiber_attrs["names"] if namesstr is None: names = ["fiber"] else: names = namesstr.split(":") # Check that these fibers exists for name in names: fsubgroup = fgroup + "/{}".format(name) if not h5file.has_dataset(fsubgroup): msg = ("H5File does not have dataset {}").format(fsubgroup) # FIXME: implement logger # logger.warning(msg) elm = VectorElement(family=family, cell=mesh.ufl_cell(), degree=int(order), quad_scheme="default") V = FunctionSpace(mesh, elm) attrs = ["f0", "s0", "n0"] for i, name in enumerate(names): func = Function(V, name=name) fsubgroup = fgroup + "/{}".format(name) h5file.read(func, fsubgroup) setattr(geo, attrs[i], func)
def _init_sub_spaces(self, num_sub_spaces): def extend_sub_function_space(sub_function_space, i): # Make sure to preserve a reference to the block function def block_function_space(self_): return self sub_function_space.block_function_space = types.MethodType( block_function_space, sub_function_space) # ... and a reference to the block index def block_index(self_): return i sub_function_space.block_index = types.MethodType( block_index, sub_function_space) # ... and that these methods are preserved by sub_function_space.sub() original_sub = sub_function_space.sub def sub(self_, j): output = original_sub(j) extend_sub_function_space(output, i) return output sub_function_space.sub = types.MethodType(sub, sub_function_space) self._num_sub_spaces = num_sub_spaces self._sub_spaces = list() for i in range(num_sub_spaces): # Extend .sub() call with the python layer of FunctionSpace sub_function_space = FunctionSpace(self._cpp_object.sub(i)) # Extend with block function space and block index methods extend_sub_function_space(sub_function_space, i) # Append self._sub_spaces.append(sub_function_space) # Finally, fill in ufl_element ufl_sub_elements = [subspace.ufl_element() for subspace in self] self._ufl_element = BlockElement(ufl_sub_elements)
def test_readme_images(): from dolfin import ( MeshEditor, Mesh, FunctionSpace, assemble, EigenMatrix, dot, grad, dx, TrialFunction, TestFunction ) import meshzoo points, cells = meshzoo.rectangle(-1.0, 1.0, -1.0, 1.0, 20, 20) # Convert points, cells to dolfin mesh editor = MeshEditor() mesh = Mesh() # topological and geometrical dimension 2 editor.open(mesh, 'triangle', 2, 2, 1) editor.init_vertices(len(points)) editor.init_cells(len(cells)) for k, point in enumerate(points): editor.add_vertex(k, point[:2]) for k, cell in enumerate(cells.astype(numpy.uintp)): editor.add_cell(k, cell) editor.close() V = FunctionSpace(mesh, 'CG', 1) u = TrialFunction(V) v = TestFunction(V) L = EigenMatrix() assemble(dot(grad(u), grad(v)) * dx, tensor=L) A = L.sparray() # M = A.T.dot(A) M = A with tempfile.TemporaryDirectory() as temp_dir: filepath = os.path.join(temp_dir, 'test.png') betterspy.write_png(filepath, M, border_width=2) # betterspy.write_png( # 'ATA.png', M, border_width=2, # colormap='viridis' # ) return
def test_save_and_checkpoint_vector(tempdir, encoding, fe_degree, fe_family, mesh_tdim, mesh_n): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") if invalid_fe(fe_family, fe_degree): pytest.skip("Trivial finite element") filename = os.path.join(tempdir, "u2_checkpoint.xdmf") mesh = mesh_factory(mesh_tdim, mesh_n) FE = VectorElement(fe_family, mesh.ufl_cell(), fe_degree) V = FunctionSpace(mesh, FE) u_in = Function(V) u_out = Function(V) if has_petsc_complex(): if mesh.geometry.dim == 1: u_out.interpolate(Expression(("x[0] + j*x[0]", ), degree=1)) elif mesh.geometry.dim == 2: u_out.interpolate( Expression(("j*x[0]*x[1]", "x[0] + j*x[0]"), degree=2)) elif mesh.geometry.dim == 3: u_out.interpolate( Expression(("j*x[0]*x[1]", "x[0] + j*x[0]", "x[2]"), degree=2)) else: if mesh.geometry.dim == 1: u_out.interpolate(Expression(("x[0]", ), degree=1)) elif mesh.geometry.dim == 2: u_out.interpolate(Expression(("x[0]*x[1]", "x[0]"), degree=2)) elif mesh.geometry.dim == 3: u_out.interpolate( Expression(("x[0]*x[1]", "x[0]", "x[2]"), degree=2)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write_checkpoint(u_out, "u_out", 0) with XDMFFile(mesh.mpi_comm(), filename) as file: u_in = file.read_checkpoint(V, "u_out", 0) u_in.vector().axpy(-1.0, u_out.vector()) assert u_in.vector().norm(cpp.la.Norm.l2) < 1.0e-12
def compute(self, get): u = get(self.valuename) if u is None: return None if not isinstance(u, Function): cbc_warning("Do not understand how to handle datatype %s" %str(type(u))) return None #if not hasattr(self, "restriction_map"): if not hasattr(self, "keys"): V = u.function_space() element = V.ufl_element() family = element.family() degree = element.degree() if LooseVersion(dolfin_version()) > LooseVersion("1.6.0"): rank = len(u.ufl_shape) else: rank = u.rank() if rank == 0: FS = FunctionSpace(self.submesh, family, degree) elif rank == 1: FS = VectorFunctionSpace(self.submesh, family, degree) elif rank == 2: FS = TensorFunctionSpace(self.submesh, family, degree, symmetry={}) self.u = Function(FS) #self.restriction_map = restriction_map(V, FS) rmap = restriction_map(V, FS) self.keys = np.array(rmap.keys(), dtype=np.intc) self.values = np.array(rmap.values(), dtype=np.intc) self.temp_array = np.zeros(len(self.keys), dtype=np.float_) # The simple __getitem__, __setitem__ has been removed in dolfin 1.5.0. # The new cbcpost-method get_set_vector should be compatible with 1.4.0 and 1.5.0. #self.u.vector()[self.keys] = u.vector()[self.values] get_set_vector(self.u.vector(), self.keys, u.vector(), self.values, self.temp_array) return self.u
def big_error_norms(self, u, overlap_subdomain): V = FunctionSpace(self.mesh, "Lagrange", self.p) uu = Function(V) uu.vector()[:] = u.vector() # uu.vector()[:] = u.vector() overlap_marker = MeshFunction('size_t', self.mesh, self.mesh.topology().dim()) overlap_subdomain.mark(overlap_marker, 1) dxo = Measure('dx', subdomain_data=overlap_marker) error = (uu**2) * dxo semi_error = inner(grad(uu), grad(uu)) * dxo L2 = assemble(error) H1 = L2 + assemble(semi_error) SH = H1 - L2 return L2, H1, SH
def test_multi_ps_vector_node_local(mesh): """Tests point source when given constructor PointSource(V, V, point, mag) with a matrix when points placed at 3 node for 1D, 2D and 3D. Local points given to constructor. """ V = FunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(Constant(0.0) * v * dx) source = [] point_coords = mesh.coordinates()[0] source.append((Point(point_coords), 10.0)) ps = PointSource(V, source) ps.apply(b) # Checks b sums to correct value size = MPI.size(mesh.mpi_comm()) b_sum = b.sum() assert round(b_sum - size * 10.0) == 0
def write_vtk_f(fname, mesh=None, nodefunctions=None,cellfunctions=None): """ Write a whole bunch of FEniCS functions to the same vtk file. """ if mesh==None: if nodefunctions != None: mesh = nodefunctions.itervalues().next().function_space().mesh() else: mesh = cellfunctions.itervalues().next().function_space().mesh() C = { 0:FunctionSpace(mesh,"DG",0), 1:VectorFunctionSpace(mesh,"DG",0), 2:TensorFunctionSpace(mesh,"DG",0) } nodefields = [(k,f.compute_vertex_values().reshape(-1,mesh.num_vertices()).T) for k,f in iteritems(nodefunctions)] if nodefunctions else None edgefields=[(k,project(f,C[f.value_rank()]).vector().get_local().reshape(mesh.num_cells(),-1) ) for k,f in iteritems(cellfunctions) ] if cellfunctions else None write_vtk(fname, mesh.cells(), mesh.coordinates(), nodefields,edgefields )
def _generate_space(expression: Operator): # Extract mesh from expression (from dolfin/fem/projection.py, _extract_function_space function) meshes = set([ufl_domain.ufl_cargo() for ufl_domain in extract_domains(expression)]) for t in traverse_unique_terminals(expression): # from ufl/domain.py, extract_domains if hasattr(t, "_mesh"): meshes.add(t._mesh) assert len(meshes) == 1 mesh = meshes.pop() # The EIM algorithm will evaluate the expression at vertices. However, since the Operator expression may # contain e.g. a gradient of a solution defined in a C^0 space, we resort to DG1 spaces. shape = expression.ufl_shape assert len(shape) in (0, 1, 2) if len(shape) == 0: space = FunctionSpace(mesh, "Discontinuous Lagrange", 1) elif len(shape) == 1: space = VectorFunctionSpace(mesh, "Discontinuous Lagrange", 1, dim=shape[0]) elif len(shape) == 2: space = TensorFunctionSpace(mesh, "Discontinuous Lagrange", 1, shape=shape) else: raise ValueError("Invalid expression in ParametrizedExpressionFactory.__init__().") return space
def test_tabulate_dofs(mesh_factory): func, args = mesh_factory mesh = func(*args) W0 = FiniteElement("Lagrange", mesh.ufl_cell(), 1) W1 = VectorElement("Lagrange", mesh.ufl_cell(), 1) W = FunctionSpace(mesh, W0 * W1) L0 = W.sub(0) L1 = W.sub(1) L01 = L1.sub(0) L11 = L1.sub(1) for i in range(mesh.num_cells()): dofs0 = L0.dofmap.cell_dofs(i) dofs1 = L01.dofmap.cell_dofs(i) dofs2 = L11.dofmap.cell_dofs(i) dofs3 = L1.dofmap.cell_dofs(i) assert len(np.intersect1d(dofs0, dofs1)) == 0 assert len(np.intersect1d(dofs0, dofs2)) == 0 assert len(np.intersect1d(dofs1, dofs2)) == 0 assert np.array_equal(np.append(dofs1, dofs2), dofs3)
def test_submesh_to_mesh_dof_map(mesh, FunctionSpace, submesh_markers, submesh, tempdir): log(PROGRESS, "Submesh to mesh dofs") V = FunctionSpace(mesh) submesh_V = convert_functionspace_to_submesh(V, submesh) (mesh_dofs_to_submesh_dofs, submesh_dofs_to_mesh_dofs) = map_functionspaces_between_mesh_and_submesh( V, mesh, submesh_V, submesh) log( PROGRESS, "Local submesh dofs ownership range: " + str(submesh_V.dofmap().ownership_range())) for (submesh_dof, mesh_dof) in submesh_dofs_to_mesh_dofs.items(): log(PROGRESS, "\t" + str(submesh_dof) + " -> " + str(mesh_dof)) assert_dof_map_plotter( V, submesh_V, "D", tempdir, "test_submesh_to_mesh_dof_map_" + FunctionSpace.__name__) filename = "test_submesh_to_mesh_dof_map_" + FunctionSpace.__name__ + "_size_" + str( MPI.size(submesh.mpi_comm())) + "_rank_" + str( MPI.rank(submesh.mpi_comm())) + ".pkl" dict_save(submesh_dofs_to_mesh_dofs, tempdir, filename) dict_assert_equal(submesh_dofs_to_mesh_dofs, data_dir, filename)
def pot(): # Define mesh and boundaries. mesh = RectangleMesh(0.0, 0.0, 0.4, 0.1, 120, 30, "left/right") V = VectorFunctionSpace(mesh, "CG", 2) Q = FunctionSpace(mesh, "CG", 1) class LeftBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] < GMSH_EPS left_boundary = LeftBoundary() class RightBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[0] > 0.4 - GMSH_EPS right_boundary = RightBoundary() class LowerBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] < GMSH_EPS lower_boundary = LowerBoundary() class UpperBoundary(SubDomain): def inside(self, x, on_boundary): return on_boundary and x[1] > 0.1 - GMSH_EPS upper_boundary = UpperBoundary() # Boundary conditions for the velocity. u_bcs = [ DirichletBC(V, (0.0, 0.0), lower_boundary), DirichletBC(V.sub(1), 0.0, upper_boundary), DirichletBC(V.sub(0), 0.0, right_boundary), DirichletBC(V.sub(0), 0.0, left_boundary), ] p_bcs = [] return mesh, V, Q, u_bcs, p_bcs, [lower_boundary], [right_boundary, left_boundary]
def eikonal_1d(mb, p0=0, function=None): "Compute distance from p0 on set of edges" # edge-to-vertex connectivity EE = np.zeros((mb.num_cells(), mb.num_vertices()), dtype=bool) for e in edges(mb): EE[e.index(), e.entities(0)] = True # vertex-to-vertex connectivity (via edges) PP = EE.T @ EE np.fill_diagonal(PP, False) # initial solution is inf everywhere sol = np.empty(PP.shape[0]) sol.fill(np.inf) # initial conditions active = deque([p0]) sol[p0] = 0.0 # fast marching on edges x = mb.coordinates() while active: curr = active.pop() neig = np.where(PP[curr, :])[0] ll = sol[curr] + np.linalg.norm(x[neig, :] - x[curr, :], axis=1) up = neig[ll < sol[neig]] active.extend(up) sol[neig] = np.minimum(sol[neig], ll) # return solution if function is None: P1e = FiniteElement("CG", mb.ufl_cell(), 1) Ve = FunctionSpace(mb, P1e) function = Function(Ve) function.vector()[vertex_to_dof_map(Ve)] = sol return function else: Ve = function.function_space() function.vector()[vertex_to_dof_map(Ve)] = sol
def test_multi_ps_vector_node(mesh): """Tests point source when given constructor PointSource(V, V, point, mag) with a matrix when points placed at 3 node for 1D, 2D and 3D. Global points given to constructor from rank 0 processor. """ point = [0.0, 0.5, 1.0] dim = mesh.geometry().dim() rank = MPI.rank(mesh.mpi_comm()) V = FunctionSpace(mesh, "CG", 1) v = TestFunction(V) b = assemble(Constant(0.0) * v * dx) source = [] point_coords = np.zeros(dim) for p in point: for i in range(dim): point_coords[i - 1] = p if rank == 0: source.append((Point(point_coords), 10.0)) ps = PointSource(V, source) ps.apply(b) # Checks b sums to correct value b_sum = b.sum() assert round(b_sum - len(point) * 10.0) == 0 # Checks values added to correct part of vector mesh_coords = V.tabulate_dof_coordinates() for p in point: for i in range(dim): point_coords[i] = p j = 0 for i in range(len(mesh_coords) // (dim)): mesh_coords_check = mesh_coords[j:j + dim - 1] if np.array_equal(point_coords, mesh_coords_check) is True: assert np.round(b.array()[j // (dim)] - 10.0) == 0.0 j += dim
def assemble_matrices(self): nedelec = FiniteElement( "Nedelec 1st kind H(curl)", self.mesh.ufl_cell(), self.nedelec_order) lagrange = FiniteElement( "Lagrange", self.mesh.ufl_cell(), self.lagrange_order) self._finite_element = nedelec*lagrange self._combined_space = FunctionSpace(self.mesh, nedelec*lagrange) # define the test and trial functions from the combined space (N_i, L_i) = TestFunctions(self._combined_space) (N_j, L_j) = TrialFunctions(self._combined_space) # construct matrices for each domain if not isinstance(self.materials, collections.Iterable): material = self.materials u_r = material.em.u_r e_r = material.em.e_r DX = material.domain (A_ij, B_ij) = em_weak_form(N_i, N_j, L_i, L_j, u_r, e_r, self._k_o_squared,DX) else: counter = 0 # a work around for summing forms for material in self.materials: u_r = material.em.u_r e_r = material.em.e_r DX = material.domain if counter == 0: (A_ij, B_ij) = em_weak_form(N_i, N_j, L_i, L_j, u_r, e_r, self._k_o_squared, DX) counter += 1 else: (a_ij, b_ij) = em_weak_form(N_i, N_j, L_i, L_j, u_r, e_r, self._k_o_squared, DX) A_ij += a_ij B_ij += b_ij # assemble the matrices assemble(A_ij, tensor=self._A) assemble(B_ij, tensor=self._B)
def print_eigenvalues(mesh): nedelec_V = FunctionSpace(mesh, "N1curl", 1) nedelec_bcs = [ DirichletBC(nedelec_V, Constant((0.0, 0.0)), DomainBoundary()) ] nedelec_eig = eigenvalues(nedelec_V, nedelec_bcs) lagrange_V = VectorFunctionSpace(mesh, "Lagrange", 1) lagrange_bcs = [ DirichletBC(lagrange_V.sub(1), 0, "near(x[0], 0) || near(x[0], pi)"), DirichletBC(lagrange_V.sub(0), 0, "near(x[1], 0) || near(x[1], pi)") ] lagrange_eig = eigenvalues(lagrange_V, lagrange_bcs) true_eig = np.sort( np.array([float(m**2 + n**2) for m in range(6) for n in range(6)]))[1:13] np.set_printoptions(formatter={'float': '{:5.2f}'.format}) print("Nedelec: {}".format(nedelec_eig)) print("Lagrange: {}".format(lagrange_eig)) print("Exact: {}".format(true_eig))
def test_save_and_read_function(tempdir): filename = os.path.join(tempdir, "function.h5") mesh = UnitSquareMesh(MPI.comm_world, 10, 10) Q = FunctionSpace(mesh, ("CG", 3)) F0 = Function(Q) F1 = Function(Q) E = Expression("x[0]", degree=1) F0.interpolate(E) # Save to HDF5 File hdf5_file = HDF5File(mesh.mpi_comm(), filename, "w") hdf5_file.write(F0, "/function") hdf5_file.close() # Read back from file hdf5_file = HDF5File(mesh.mpi_comm(), filename, "r") F1 = hdf5_file.read_function(Q, "/function") F0.vector().axpy(-1.0, F1.vector()) assert F0.vector().norm(dolfin.cpp.la.Norm.l2) < 1.0e-12 hdf5_file.close()
def FunctionSpace(self, mesh = None, rank = 0): """ Returns a function space for a mesh. *Arguments* mesh (:class:`dolfin.Mesh`) the mesh, defaults to mesh of the state if set to :code:`None` rank (:class:`int`) the rank of the function space (0 for scalar space, 1 for vector space) *Returns* :class:`dolfin.FunctionSpace` the function space """ if rank == 0: if mesh == None: return self._VS element = self._VS.ufl_element() return FunctionSpace(mesh, element.family(), element.degree()) elif rank == 1: return self.VectorFunctionSpace(mesh) else: raise Exception("Rank > 1 not supported.")
def compute_mu(constant=True): """ Compute mu as according to arxiv paper https://arxiv.org/pdf/1509.08601.pdf """ mu_min=Constant(1) mu_max=Constant(500) if constant: return mu_max else: V = FunctionSpace(self.mesh, "CG",1) u, v = TrialFunction(V), TestFunction(V) a = inner(grad(u),grad(v))*dx l = Constant(0)*v*dx bcs = [] for marker in self.move_dict["Fixed"]: bcs.append(DirichletBC(V, mu_min, self.mf, marker)) for marker in self.move_dict["Deform"]: bcs.append(DirichletBC(V, mu_max, self.mf, marker)) mu = Function(V) solve(a==l, mu, bcs=bcs) return mu
def get_norm(u, uh): assert len(subdomains) == len(u) V = uh.function_space() mesh = V.mesh() cell_f = MeshFunction('size_t', mesh, mesh.topology().dim(), 0) error = 0 for subd_i, u_i in zip(subdomains, u): cell_f.set_all(0) # Reset! # Pick an edge subd_i.mark(cell_f, 1) mesh_i = SubMesh(mesh, cell_f, 1) # Edge local function space Vi = FunctionSpace(mesh_i, V.ufl_element()) # The solution on it uh_i = interpolate(uh, Vi) # And the error there error_i = norm(u_i, uh_i) error += error_i**2 error = sqrt(error) return error
def adaptive(self, mesh, eigv, eigf): """Refine mesh based on residual errors.""" fraction = 0.1 C = FunctionSpace(mesh, "DG", 0) # constants on triangles w = TestFunction(C) h = CellSize(mesh) n = FacetNormal(mesh) marker = CellFunction("bool", mesh) print len(marker) indicators = np.zeros(len(marker)) for e, u in zip(eigv, eigf): errform = avg(h) * jump(grad(u), n) ** 2 * avg(w) * dS \ + h * (inner(grad(u), n) - Constant(e) * u) ** 2 * w * ds if self.degree > 1: errform += h**2 * div(grad(u))**2 * w * dx indicators[:] += assemble(errform).array() # errors for each cell print "Residual error: ", sqrt(sum(indicators) / len(eigv)) cutoff = sorted(indicators, reverse=True)[int(len(indicators) * fraction) - 1] marker.array()[:] = indicators > cutoff # mark worst errors mesh = refine(mesh, marker) return mesh
def __init__(self, Th, callback_type): # Create mesh and define function space mesh = UnitSquareMesh(Th, Th) self.V = FunctionSpace(mesh, "Lagrange", 1) # Define variational problem u = TrialFunction(self.V) v = TestFunction(self.V) self.a = inner(grad(u), grad(v)) * dx + inner(u, v) * dx self.f = lambda g: g * v * dx # Define callback function depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": def callback(arg): return arg elif callback_type == "tensor callbacks": def callback(arg): return assemble(arg) self.callback_type = callback_type self.callback = callback
def __init__(self, Th, callback_type): # Create mesh and define function space mesh = UnitSquareMesh(Th, Th) self.V = FunctionSpace(mesh, "Lagrange", 1) # Define variational problem du = TrialFunction(self.V) v = TestFunction(self.V) self.u = Function(self.V) self.r = lambda u, g: inner(grad(u), grad(v))*dx + inner(u + u**3, v)*dx - g*v*dx self.j = lambda u, r: derivative(r, u, du) # Define initial guess self.initial_guess_expression = Expression("0.1 + 0.9*x[0]*x[1]", element=self.V.ufl_element()) # Define callback function depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": def callback(arg): return arg elif callback_type == "tensor callbacks": def callback(arg): return assemble(arg) self.callback_type = callback_type self.callback = callback
def P0surf_to_DLT0_map(facet_f, tags): ''' Compute mapping for using DLT0 functions to set P0 functions on the embedded mesh of entities where facet_f == tags ''' # The idea here is that we only want to include in the submesh the # facets which this process can write to. This is determined by auxiliary # DLT0 space, because we want to represent data by P0 on the neuron # surface mesh mesh = facet_f.mesh() L = FunctionSpace(mesh, 'Discontinuous Lagrange Trace', 0) tdim = mesh.topology().dim() dm = L.dofmap() # Mapping of facets to degrees of freedom ... facet2Ldofs = np.array(dm.entity_closure_dofs(mesh, tdim-1)) # ... we are only interested in not-ghosts facet2Ldofs, ghosts = facet2Ldofs[:mesh.topology().ghost_offset(tdim-1)], facet2Ldofs[mesh.topology().ghost_offset(tdim-1):] # And further we want to filter by ownership first, last = dm.ownership_range() global_dofs = np.fromiter(map(dm.local_to_global_index, facet2Ldofs), dtype=facet2Ldofs.dtype) owned, = np.where(np.logical_and(global_dofs >= first, global_dofs < last)) # So when we will build the mesh out of marked entities ignore = set(range(mesh.num_entities(tdim-1))) - set(owned) # Now we want to create mesh for the neuron surface where each cell # is for one facet owned by DLT comm = MPI.comm_self # The mesh is always local surface_mesh = EmbeddedMesh(facet_f, tags, comm, ignored_entities=ignore) ncells = surface_mesh.num_cells() # For io, whatever we want to evalute the idea is to first interpolate # it to DLT and then assign as if to P0 function on the mesh using if ncells > 0: c2f = surface_mesh.parent_entity_map[mesh.id()][tdim-1] cell2Ldofs = np.array([facet2Ldofs[c2f[c]] for c in range(ncells)]) else: cell2Ldofs = [] return surface_mesh, L, cell2Ldofs
def __getattr__(self, attr): if attr in self._cache: return self._cache[attr] materials = {} for domain, material in self._materials.items(): ids = self._state.domain_ids(domain) for id in ids: if materials.has_key(id): materials[id] = Material(materials[id], material) else: materials[id] = material # scalar or vector parameter V = None expr = None if len(self._materials) == 0: self._cache[attr] = Constant(getattr(self._base_material, attr)) else: for material in [self._base_material] + self._materials.values(): try: value = getattr(material, attr) if isinstance(value, tuple) or isinstance(value, list): assert len(value) == 3 V = VectorFunctionSpace(self._state.mesh, 'DG', 0) expr = VectorCellExpr(attr, self._state.cell_domains, self._base_material, materials) else: V = FunctionSpace(self._state.mesh, 'DG', 0) expr = CellExpr(attr, self._state.cell_domains, self._base_material, materials) break except AttributeError: continue self._cache[attr] = interpolate(expr, V) return self._cache[attr]
def PVDTempSeries(path, V=None, first=0, last=None): ''' Read in the temp series of functions in V from PVD file. If V is not a function space then a finite element has to be provided for constructing the space on the recovered mesh. ''' _, ext = os.path.splitext(path) assert ext == '.pvd' tree = ET.parse(path) collection = list(tree.getroot())[0] path = os.path.dirname(os.path.abspath(path)) # Read in paths/timestamps for VTUs. NOTE: as thus is supposed to be serial # assert part 0 vtus, times = [], [] for dataset in collection: assert dataset.attrib['part'] == '0' vtus.append(os.path.join(path, dataset.attrib['file'])) times.append(float(dataset.attrib['timestep'])) vtus, times = vtus[slice(first, last, None)], times[slice(first, last, None)] # path.vtu -> function. But vertex values!!!! if not isinstance(V, FunctionSpace): warning('Setting up P1 space on the recovered mesh') cell_type = V.cell() # Dangerously assuming this is a UFL element mesh = read_vtu_mesh(vtus[0], cell_type) V = FunctionSpace(mesh, V) V = get_P1_space(V) functions = read_vtu_function(vtus, V) ft_pairs = zip(functions, times) return TempSeries(ft_pairs)
def test_lu_cholesky(): """Test that PETScLUSolver selects LU or Cholesky solver based on symmetry of matrix operator. """ from petsc4py import PETSc mesh = UnitSquareMesh(mpi_comm_world(), 12, 12) V = FunctionSpace(mesh, "Lagrange", 1) u, v = TrialFunction(V), TestFunction(V) A = PETScMatrix(mesh.mpi_comm()) assemble(Constant(1.0)*u*v*dx, tensor=A) # Check that solver type is LU solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc") pc_type = solver.ksp().getPC().getType() assert pc_type == "lu" # Set symmetry flag A.mat().setOption(PETSc.Mat.Option.SYMMETRIC, True) # Check symmetry flags symm = A.mat().isSymmetricKnown() assert symm[0] == True assert symm[1] == True # Check that solver type is Cholesky since matrix has now been # marked as symmetric solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc") pc_type = solver.ksp().getPC().getType() assert pc_type == "cholesky" # Re-assemble, which resets symmetry flag assemble(Constant(1.0)*u*v*dx, tensor=A) solver = PETScLUSolver(mesh.mpi_comm(), A, "petsc") pc_type = solver.ksp().getPC().getType() assert pc_type == "lu"
def funvec2imgseq(v: np.array, m: int, n: int, o: int) -> np.array: """Takes values of piecewise linear interpolation of a function at the vertices and returns a 3-dimensional array. Each degree of freedom corresponds to one pixel in the array of size (m, n, o). Args: v (np.array): Values at vertices of triangle mesh. m (int): The number of rows. n (int): The number of columns. Returns: np.array: An array of size (m, n, o). """ # Create image. img = np.zeros((m, n, o)) # Create mesh and function space. mesh = UnitCubeMesh(m-1, n-1, o-1) mc = mesh.coordinates().reshape((-1, 3)) # Evaluate function at vertices. hx, hy, hz = 1./(m-1), 1./(n-1), 1./(o-1) x = np.array(np.round(mc[:, 0]/hx), dtype=int) y = np.array(np.round(mc[:, 1]/hy), dtype=int) z = np.array(np.round(mc[:, 2]/hz), dtype=int) # Create function space and function. V = FunctionSpace(mesh, 'CG', 1) # Create image from function. v2d = vertex_to_dof_map(V) values = v[v2d] for (i, j, k, v) in zip(x, y, z, values): img[i, j, k] = v return img
def test_readonly_view_local_to_global_unwoned(mesh): """Test that local_to_global_unwoned() returns readonly view into the data; in particular test lifetime of data owner""" V = FunctionSpace(mesh, "P", 1) dofmap = V.dofmap() index_map = dofmap().index_map rc = sys.getrefcount(dofmap) l2gu = dofmap.local_to_global_unowned() assert sys.getrefcount(dofmap) == rc + 1 if l2gu.size else rc assert not l2gu.flags.writeable assert all(l2gu < V.dofmap().global_dimension()) del l2gu assert sys.getrefcount(dofmap) == rc rc = sys.getrefcount(index_map) l2gu = index_map.local_to_global_unowned() assert sys.getrefcount(index_map) == rc + 1 if l2gu.size else rc assert not l2gu.flags.writeable assert all(l2gu < V.dofmap().global_dimension()) del l2gu assert sys.getrefcount(index_map) == rc
def test_petsc4py_matrix(pushpop_parameters): "Test PETScMatrix <-> petsc4py.PETSc.Mat conversions" parameters["linear_algebra_backend"] = "PETSc" # Assemble a test matrix mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, "Lagrange", 1) u, v = TrialFunction(V), TestFunction(V) a = u * v * dx A1 = assemble(a) # Test conversion dolfin.PETScMatrix -> petsc4py.PETSc.Mat A1 = as_backend_type(A1) M1 = A1.mat() # Copy and scale matrix with petsc4py M2 = M1.copy() M2.scale(2.0) # Test conversion petsc4py.PETSc.Mat -> PETScMatrix A2 = PETScMatrix(M2) assert (A1.array() * 2.0 == A2.array()).all()