def coarsen_form(form): """Return a coarse mesh version of a form :arg form: The :class:`~ufl.classes.Form` to coarsen. This maps over the form and replaces coefficients and arguments with their coarse mesh equivalents.""" if form is None: return None assert isinstance(form, ufl.Form), \ "Don't know how to coarsen %r" % type(form) mapper = CoarsenIntegrand() forms = [] # Ugh, visitors can't deal with measures (they're not actual # Exprs) so we need to map the transformer over the integrand and # reconstruct the integral by building the measure by hand. for it in form.integrals(): integrand = map_expr_dag(mapper, it.integrand()) mesh = it.ufl_domain() hierarchy, level = utils.get_level(mesh) new_mesh = hierarchy[level - 1] measure = ufl.Measure(it.integral_type(), domain=new_mesh, subdomain_id=it.subdomain_id(), subdomain_data=it.subdomain_data(), metadata=it.metadata()) forms.append(integrand * measure) return reduce(add, forms)
def test_interpolate_subset(order, dim, affine): if dim == 2: ct = CellType.triangle if affine else CellType.quadrilateral mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct) elif dim == 3: ct = CellType.tetrahedron if affine else CellType.hexahedron mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct) V = FunctionSpace(mesh, ("DG", order)) u = Function(V) cells = locate_entities(mesh, mesh.topology.dim, lambda x: x[1] <= 0.5 + 1e-10) num_local_cells = mesh.topology.index_map(mesh.topology.dim).size_local cells_local = cells[cells < num_local_cells] x = ufl.SpatialCoordinate(mesh) f = x[1]**order expr = Expression(f, V.element.interpolation_points) u.interpolate(expr, cells_local) mt = MeshTags(mesh, mesh.topology.dim, cells_local, np.ones(cells_local.size, dtype=np.int32)) dx = ufl.Measure("dx", domain=mesh, subdomain_data=mt) assert np.isclose( np.abs(form(assemble_scalar(form(ufl.inner(u - f, u - f) * dx(1))))), 0) integral = mesh.comm.allreduce(assemble_scalar(form(u * dx)), op=MPI.SUM) assert np.isclose(integral, 1 / (order + 1) * 0.5**(order + 1), 0)
def test_assembly_dx_domains(mode): mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 10, 10, ghost_mode=mode) V = dolfinx.FunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) # Prepare a marking structures # indices cover all cells # values are [1, 2, 3, 3, ...] cell_map = mesh.topology.index_map(mesh.topology.dim) num_cells = cell_map.size_local + cell_map.num_ghosts indices = numpy.arange(0, num_cells) values = numpy.full(indices.shape, 3, dtype=numpy.intc) values[0] = 1 values[1] = 2 marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim, indices, values) dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh) w = dolfinx.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) bc = dolfinx.fem.DirichletBC(dolfinx.Function(V), range(30)) # Assemble matrix a = w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3)) A = dolfinx.fem.assemble_matrix(a) A.assemble() a2 = w * ufl.inner(u, v) * dx A2 = dolfinx.fem.assemble_matrix(a2) A2.assemble() assert (A - A2).norm() < 1.0e-12 # Assemble vector L = ufl.inner(w, v) * (dx(1) + dx(2) + dx(3)) b = dolfinx.fem.assemble_vector(L) dolfinx.fem.apply_lifting(b, [a], [[bc]]) b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) dolfinx.fem.set_bc(b, [bc]) L2 = ufl.inner(w, v) * dx b2 = dolfinx.fem.assemble_vector(L2) dolfinx.fem.apply_lifting(b2, [a], [[bc]]) b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) dolfinx.fem.set_bc(b2, [bc]) assert (b - b2).norm() < 1.0e-12 # Assemble scalar L = w * (dx(1) + dx(2) + dx(3)) s = dolfinx.fem.assemble_scalar(L) s = mesh.mpi_comm().allreduce(s, op=MPI.SUM) assert s == pytest.approx(0.5, 1.0e-12) L2 = w * dx s2 = dolfinx.fem.assemble_scalar(L2) s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM) assert s == pytest.approx(s2, 1.0e-12)
def test_assembly_dx_domains(mesh): V = dolfinx.FunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) # Prepare a marking structures # indices cover all cells # values are [1, 2, 3, 3, ...] imap = mesh.topology.index_map(mesh.topology.dim) num_cells = imap.size_local + imap.num_ghosts indices = numpy.arange(0, num_cells) values = numpy.full(indices.shape, 3, dtype=numpy.intc) values[0] = 1 values[1] = 2 marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim, indices, values) dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh) w = dolfinx.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) # Assemble matrix a = w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3)) A = dolfinx.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * dx A2 = dolfinx.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # Assemble vector L = ufl.inner(w, v) * (dx(1) + dx(2) + dx(3)) b = dolfinx.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) L2 = ufl.inner(w, v) * dx b2 = dolfinx.fem.assemble_vector(L2) b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # Assemble scalar L = w * (dx(1) + dx(2) + dx(3)) s = dolfinx.fem.assemble_scalar(L) s = mesh.mpi_comm().allreduce(s, op=MPI.SUM) L2 = w * dx s2 = dolfinx.fem.assemble_scalar(L2) s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM) assert (s == pytest.approx(s2, 1.0e-12) and 0.5 == pytest.approx(s, 1.0e-12))
def test_assembly_ds_domains(mesh): V = dolfinx.FunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) marker = dolfinx.MeshFunction("size_t", mesh, mesh.topology.dim - 1, 0) def bottom(x): return numpy.isclose(x[1], 0.0) def top(x): return numpy.isclose(x[1], 1.0) def left(x): return numpy.isclose(x[0], 0.0) def right(x): return numpy.isclose(x[0], 1.0) marker.mark(bottom, 111) marker.mark(top, 222) marker.mark(left, 333) marker.mark(right, 444) ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh) w = dolfinx.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) # Assemble matrix a = w * ufl.inner(u, v) * (ds(111) + ds(222) + ds(333) + ds(444)) A = dolfinx.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * ds A2 = dolfinx.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # Assemble vector L = ufl.inner(w, v) * (ds(111) + ds(222) + ds(333) + ds(444)) b = dolfinx.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) L2 = ufl.inner(w, v) * ds b2 = dolfinx.fem.assemble_vector(L2) b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # Assemble scalar L = w * (ds(111) + ds(222) + ds(333) + ds(444)) s = dolfinx.fem.assemble_scalar(L) s = dolfinx.MPI.sum(mesh.mpi_comm(), s) L2 = w * ds s2 = dolfinx.fem.assemble_scalar(L2) s2 = dolfinx.MPI.sum(mesh.mpi_comm(), s2) assert (s == pytest.approx(s2, 1.0e-12) and 2.0 == pytest.approx(s, 1.0e-12))
def test_assembly_dx_domains(mode, meshtags_factory): mesh = create_unit_square(MPI.COMM_WORLD, 10, 10, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) # Prepare a marking structures # indices cover all cells # values are [1, 2, 3, 3, ...] cell_map = mesh.topology.index_map(mesh.topology.dim) num_cells = cell_map.size_local + cell_map.num_ghosts indices = np.arange(0, num_cells) values = np.full(indices.shape, 3, dtype=np.intc) values[0] = 1 values[1] = 2 marker = meshtags_factory(mesh, mesh.topology.dim, indices, values) dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh) w = Function(V) w.x.array[:] = 0.5 # Assemble matrix a = form(w * ufl.inner(u, v) * (dx(1) + dx(2) + dx(3))) A = assemble_matrix(a) A.assemble() a2 = form(w * ufl.inner(u, v) * dx) A2 = assemble_matrix(a2) A2.assemble() assert (A - A2).norm() < 1.0e-12 bc = dirichletbc(Function(V), range(30)) # Assemble vector L = form(ufl.inner(w, v) * (dx(1) + dx(2) + dx(3))) b = assemble_vector(L) apply_lifting(b, [a], [[bc]]) b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) set_bc(b, [bc]) L2 = form(ufl.inner(w, v) * dx) b2 = assemble_vector(L2) apply_lifting(b2, [a], [[bc]]) b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) set_bc(b2, [bc]) assert (b - b2).norm() < 1.0e-12 # Assemble scalar L = form(w * (dx(1) + dx(2) + dx(3))) s = assemble_scalar(L) s = mesh.comm.allreduce(s, op=MPI.SUM) assert s == pytest.approx(0.5, 1.0e-12) L2 = form(w * dx) s2 = assemble_scalar(L2) s2 = mesh.comm.allreduce(s2, op=MPI.SUM) assert s == pytest.approx(s2, 1.0e-12)
def norm_L2(u): """ Returns the L2 norm of the function u """ comm = u.function_space.mesh.comm dx = ufl.Measure("dx", u.function_space.mesh) norm_form = form(ufl.inner(u, u) * dx) norm = np.sqrt( comm.allreduce(assemble_scalar(norm_form), op=mpi4py.MPI.SUM)) return norm
def assemble(mesh, space, k): V = fem.FunctionSpace(mesh, (space, k)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) dx = ufl.Measure("dx", domain=mesh) a = fem.form(ufl.inner(u, v) * dx) A = fem.petsc.assemble_matrix(a) A.assemble() return A
def translate_facetarea(terminal, mt, ctx): assert ctx.integral_type != 'cell' domain = terminal.ufl_domain() integrand, degree = one_times(ufl.Measure(ctx.integral_type, domain=domain)) config = {name: getattr(ctx, name) for name in ["ufl_cell", "integration_dim", "entity_ids", "precision", "index_cache"]} config.update(interface=ctx, quadrature_degree=degree) expr, = compile_ufl(integrand, point_sum=True, **config) return expr
def test_facet_area1D(): mesh = create_unit_interval(MPI.COMM_WORLD, 10) # NOTE: Area of a vertex is defined to 1 in ufl c0 = ufl.FacetArea(mesh) c = Constant(mesh, ScalarType(1)) ds = ufl.Measure("ds", domain=mesh) a0 = mesh.comm.allreduce(assemble_scalar(form(c * ds)), op=MPI.SUM) a = mesh.comm.allreduce(assemble_scalar(form(c0 * ds)), op=MPI.SUM) assert numpy.isclose(a.real, 2) assert numpy.isclose(a0.real, 2)
def initialize_geometry(self, mesh, facet_domains=None, cell_domains=None): """Stores mesh, domains and related quantities in a canonical member naming. Creates attributes on self: - mesh - facet_domains - cell_domains - ds - dS - dx """ # Store geometry properties self.mesh = mesh self.facet_domains = facet_domains self.cell_domains = cell_domains # Fetch domains from mesh if necessary and avaiable domains = mesh.domains() if domains is not None: dim = mesh.geometry().dim() if self.facet_domains is None: self.facet_domains = MeshFunction("size_t", mesh, dim - 1, domains) if self.cell_domains is None: self.cell_domains = MeshFunction("size_t", mesh, dim, domains) # Attach domains to measures for convenience self.ds = ufl.Measure("ds", domain=self.mesh, subdomain_data=self.facet_domains) self.dS = ufl.Measure("dS", domain=self.mesh, subdomain_data=self.facet_domains) self.dx = ufl.Measure("dx", domain=self.mesh, subdomain_data=self.cell_domains)
def facet_avg(self, o): if self.context.integral_type == "cell": raise ValueError("Can't take FacetAvg in cell integral") integrand, = o.ufl_operands domain = o.ufl_domain() measure = ufl.Measure(self.context.integral_type, domain=domain) integrand, degree, argument_multiindices = entity_avg(integrand / CellVolume(domain), measure, self.context.argument_multiindices) config = {name: getattr(self.context, name) for name in ["ufl_cell", "precision", "index_cache"]}, config.update(quadrature_degree=degree, interface=self.context, argument_multiindices=argument_multiindices) expr, = compile_ufl(integrand, point_sum=True, **config) return expr
def blocks(self): dx = ufl.Measure("dx", self.mesh) u, p = self.uu_[0:2] v, q = self.vv_[0:2] aa = [[ ufl.inner(self.sigma(u), symgrad(v)) * dx, ufl.inner(p, v) * dx ], [ufl.inner(q, u) * dx, 0]] # Notice that dot(sigma(Eps), symgrad(v)) = dot(Eps, sigma(symgrad(v))) ff = [-ufl.inner(self.Eps, self.sigma(v)) * dx, 0] return [aa, ff]
def blocks(self): aa, ff = super(FormulationMinimallyConstrained, self).blocks() n = ufl.FacetNormal(self.mesh) ds = ufl.Measure("ds", self.mesh) u, P = self.uu_[0], self.uu_[2] v, Q = self.vv_[0], self.vv_[2] aa[0].append(-ufl.inner(P, ufl.outer(v, n)) * ds) aa[1].append(0) aa.append([-ufl.inner(Q, ufl.outer(u, n)) * ds, 0, 0]) ff.append(0) return [aa, ff]
def test_facet_area(mesh_factory): """ Compute facet area of cell. UFL currently only supports affine cells for this computation """ # NOTE: UFL only supports facet area calculations of affine cells func, args, exact_area = mesh_factory mesh = func(*args) c0 = ufl.FacetArea(mesh) c = Constant(mesh, ScalarType(1)) tdim = mesh.topology.dim num_faces = 4 if tdim == 2 else 6 ds = ufl.Measure("ds", domain=mesh) a = mesh.comm.allreduce(assemble_scalar(form(c * ds)), op=MPI.SUM) a0 = mesh.comm.allreduce(assemble_scalar(form(c0 * ds)), op=MPI.SUM) assert numpy.isclose(a.real, num_faces) assert numpy.isclose(a0.real, num_faces * exact_area)
def cell_avg(self, o): if self.context.integral_type != "cell": # Need to create a cell-based quadrature rule and # translate the expression using that (c.f. CellVolume # below). raise NotImplementedError("CellAvg on non-cell integrals not yet implemented") integrand, = o.ufl_operands domain = o.ufl_domain() measure = ufl.Measure(self.context.integral_type, domain=domain) integrand, degree, argument_multiindices = entity_avg(integrand / CellVolume(domain), measure, self.context.argument_multiindices) config = {name: getattr(self.context, name) for name in ["ufl_cell", "precision", "index_cache"]} config.update(quadrature_degree=degree, interface=self.context, argument_multiindices=argument_multiindices) expr, = compile_ufl(integrand, point_sum=True, **config) return expr
def blocks(self): aa, ff = super(FormulationDirichletLagrange, self).blocks() uD = self.others["uD"] if "uD" in self.others else df.Constant((0, 0)) ds = ufl.Measure("ds", self.mesh) u, p = self.uu_[0], self.uu_[2] v, q = self.vv_[0], self.vv_[2] aa[0].append(ufl.inner(p, v) * ds) aa[1].append(0) aa.append([ufl.inner(q, u) * ds, 0, 0]) ff.append(ufl.inner(q, uD) * ds) return [aa, ff]
def get_tangent(self): if self.Chom_ is None: self.Chom_ = np.zeros((self.nvoigt, self.nvoigt)) dy = ufl.Measure("dx", self.mesh) vol = df.assemble(df.Constant(1.0) * dy) y = ufl.SpatialCoordinate(self.mesh) Eps = df.Constant(((0., 0.), (0., 0.))) # just placeholder form = self.multiscale_model(self.mesh, self.sigma_law, Eps, self.others) a, f, bcs, W = form() start = timer() A = mp.block_assemble(a) if len(bcs) > 0: bcs.apply(A) # decompose just once, since the matrix A is the same in every solve solver = df.PETScLUSolver("superlu") sol = mp.BlockFunction(W) end = timer() print("time assembling system", end - start) for i in range(self.nvoigt): start = timer() Eps.assign(df.Constant(self.macro_strain(i))) F = mp.block_assemble(f) if len(bcs) > 0: bcs.apply(F) solver.solve(A, sol.block_vector(), F) sol.block_vector().block_function().apply("to subfunctions") sig_mu = self.sigma_law(df.dot(Eps, y) + sol[0]) sigma_hom = self.integrate(sig_mu, dy, (2, 2)) / vol self.Chom_[:, i] = sigma_hom.flatten()[[0, 3, 1]] end = timer() print("time in solving system", end - start) return self.Chom_
window_size=[2 * figsize, figsize]) else: subplotter.show() # Plotting a dolfinx.Function # =========================== # In the previous sections we have considered CG-1 spaces, which have a # 1-1 correspondence with the vertices of the geometry. To be able to # plot higher order function spaces, both CG and DG spaces, we have to # adjust our plotting technique. # We start by projecting a discontinuous function into a second order DG # space Note that we use the `cell_tags` from the previous section to # restrict the integration domain on the RHS. dx = ufl.Measure("dx", subdomain_data=cell_tags) V = dolfinx.FunctionSpace(mesh, ("DG", 2)) uh = dolfinx.Function(V) u = ufl.TrialFunction(V) v = ufl.TestFunction(V) x = ufl.SpatialCoordinate(mesh) a = ufl.inner(u, v) * dx L = ufl.inner(x[0], v) * dx(1) + ufl.inner(0.01, v) * dx(0) problem = dolfinx.fem.LinearProblem(a, L, u=uh, petsc_options={ "ksp_type": "preonly", "pc_type": "lu" }) problem.solve()
def __init__(self, mesh, k, omega, c, wx, wy, amp): P = FiniteElement("Lagrange", mesh.ufl_cell(), k) self.V = FunctionSpace(mesh, P) self.u, self.v = Function(self.V), Function(self.V) self.g = Function(self.V) self.g_deriv = Function(self.V) self.omega = omega self.c = c self.a = amp # GEOMETRY: rectangular domain with 5mm radius piston on left wall # |------------------------------------------------------------| # | | # | | # || | # || | # || <-- 5mm radius piston | # || | # || | # | | # | | # |----------------------------------------------------------- | # Locate boundary facets tdim = mesh.topology.dim # facets0 belong to 5mm radius piston at x=0 facets0 = locate_entities_boundary(mesh, tdim - 1, lambda x: (x[0] < 1.0e-6) * (np.abs(x[1]) < 5e-3)) # facets1 belong to right hand wall, at x=wx facets1 = locate_entities_boundary(mesh, tdim - 1, lambda x: x[0] > (wx - 1.0e-6)) # facets2 belong to top and bottom walls, at y=+wy/2 and y=-wy/2 facets2 = locate_entities_boundary(mesh, tdim - 1, lambda x: np.abs(x[1]) > (wy / 2 - 1.0e-6)) indices, pos = np.unique(np.hstack((facets0, facets1, facets2)), return_index=True) values = np.hstack((np.full(facets0.shape, 1, np.intc), np.full(facets1.shape, 2, np.intc), np.full(facets2.shape, 3, np.intc))) marker = dolfinx.mesh.MeshTags(mesh, tdim - 1, indices, values[pos]) ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh) # dv, p = TrialFunction(self.V), TestFunction(self.V) p = TestFunction(self.V) beta = 3.5 delta0 = 3.0e-6 delta = delta0 # # EXPERIMENT: add absorbing layers to top and bottom ("PMLs") # def delta_fun(x): # lam = 2 * np.pi / k # depth = 2 * lam # dist = np.abs(x[1]) - (wy/2 - depth) # inside = (dist >= 0) # # outside = (dist < 0) # return delta0 + inside * (dist**2) * 1e3 # delta = Function(self.V) # delta.interpolate(delta_fun) # delta.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, # mode=PETSc.ScatterMode.FORWARD) # with XDMFFile(mesh.mpi_comm(), "delta.xdmf", "w", # encoding=XDMFFile.Encoding.HDF5) as file: # file.write_mesh(mesh) # file.write_function(delta) # Westervelt equation self.L1 = - inner(grad(self.u), grad(p)) * dx \ - (delta / c**2) * inner(grad(self.v), grad(p)) * dx \ + (2 * beta / (rho * c**4)) * inner(self.v * self.v, p) * dx \ - (1 / c) * inner(self.v, p) * ds \ + inner(self.g, p) * ds(1) \ + (delta / c**2) * inner(self.g_deriv, p) * ds(1) self.lumped = True # Vector to be re-used for assembly self.b = None # TODO: precompile/pre-process Form L if self.lumped: # Westervelt equation a = (1 / c**2) * \ (1 - 2 * beta * self.u / (rho * c**2)) * p * dx(degree=k) \ + (delta / c**3) * p * ds self.M = dolfinx.fem.assemble_vector(a) self.M.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) else: # TODO: non-lumped version of Westervelt # a = (1 / self.c**2) * inner(dv, p) * dx(degree=k * k) M = dolfinx.fem.assemble_matrix(a) M.assemble() self.solver = PETSc.KSP().create(mesh.mpi_comm()) opts = PETSc.Options() opts["ksp_type"] = "cg" opts["ksp_rtol"] = 1.0e-8 self.solver.setFromOptions() self.solver.setOperators(M)
# u_t = (b.value[1] * rho.value * dz * dy * dx**4) / (8 * 2 * mu.value * dz * dy**3 / 12) # print(f"u_t = {u_t} [m]") # ω_0 = numpy.sqrt((2 * mu.value * dz * dy**3 / 12) / (rho.value * dz * dy * dx**4)) * numpy.array([1.875**2, 4.694**2]) # T_0 = 2 * numpy.pi / ω_0 # print(f"ω_0 = {ω_0} [rad/s]") # print(f"T_0 = {T_0} [s]") # Global time time = dolfinx.fem.Constant(mesh, 0.0) # [s] # Time step size dt = dolfinx.fem.Constant(mesh, 1e-2) # [s] # Number of time steps nT = 200 # Define integration measures dx = ufl.Measure("dx", domain=mesh, subdomain_data=subdomains) ds = ufl.Measure("ds", domain=mesh, subdomain_data=interfaces) # Function spaces Ue = ufl.VectorElement("CG", mesh.ufl_cell(), 2) Uf = dolfinx.fem.FunctionSpace(mesh, Ue) # Define functions u = dolfinx.fem.Function(Uf, name="u") ut = dolfinx.fem.Function(Uf, name="ut") utt = dolfinx.fem.Function(Uf, name="utt") u_ = dolfinx.fem.Function(Uf, name="u_") # boundary conditions δu = ufl.TestFunction(Uf)
file.write_mesh(mesh) # Function spaces element_u = ufl.VectorElement("Lagrange", mesh.ufl_cell(), degree=1, dim=tdim) V_u = dolfinx.fem.FunctionSpace(mesh, element_u) # Define the state u = dolfinx.fem.Function(V_u, name="Displacement") u_ = dolfinx.fem.Function(V_u, name="Boundary Displacement") ux_ = dolfinx.fem.Function(V_u.sub(0).collapse(), name="Boundary Displacement") zero_u = dolfinx.fem.Function(V_u, name=" Boundary Displacement") state = {"u": u} # Measures dx = ufl.Measure("dx", domain=mesh) ds = ufl.Measure("ds", domain=mesh) dofs_u_left = dolfinx.fem.locate_dofs_geometrical( V_u, lambda x: np.isclose(x[0], 0.0)) dofs_u_right = dolfinx.fem.locate_dofs_geometrical( V_u, lambda x: np.isclose(x[0], Lx)) dofs_ux_right = dolfinx.fem.locate_dofs_geometrical( (V_u.sub(0), V_u.sub(0).collapse()), lambda x: np.isclose(x[0], Lx)) # Set Bcs Function zero_u.interpolate(lambda x: (np.zeros_like(x[0]), np.zeros_like(x[1]))) u_.interpolate(lambda x: (np.ones_like(x[0]), 0 * np.ones_like(x[1]))) ux_.interpolate(lambda x: np.ones_like(x[0])) for f in [zero_u, ux_]:
def test_assembly_dx_domains(mesh): V = dolfin.FunctionSpace(mesh, ("CG", 1)) u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V) marker = dolfin.MeshFunction("size_t", mesh, mesh.topology.dim, 0) values = marker.values # Mark first, second and all other # Their union is the whole domain values[0] = 111 values[1] = 222 values[2:] = 333 dx = ufl.Measure('dx', subdomain_data=marker, domain=mesh) w = dolfin.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) # # Assemble matrix # a = w * ufl.inner(u, v) * (dx(111) + dx(222) + dx(333)) A = dolfin.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * dx A2 = dolfin.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # # Assemble vector # L = ufl.inner(w, v) * (dx(111) + dx(222) + dx(333)) b = dolfin.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) L2 = ufl.inner(w, v) * dx b2 = dolfin.fem.assemble_vector(L2) b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # # Assemble scalar # L = w * (dx(111) + dx(222) + dx(333)) s = dolfin.fem.assemble_scalar(L) s = dolfin.MPI.sum(mesh.mpi_comm(), s) L2 = w * dx s2 = dolfin.fem.assemble_scalar(L2) s2 = dolfin.MPI.sum(mesh.mpi_comm(), s2) assert (s == pytest.approx(s2, 1.0e-12) and 0.5 == pytest.approx(s, 1.0e-12))
def test_simple_triangle(): if MPI.COMM_WORLD.rank == 0: import gmsh gmsh.initialize() gmsh.model.add("test") p0 = gmsh.model.geo.addPoint(0.0, 0.0, 0.0) p1 = gmsh.model.geo.addPoint(1.0, 0.0, 0.0) p2 = gmsh.model.geo.addPoint(1.0, 1.0, 0.0) p3 = gmsh.model.geo.addPoint(0.0, 1.0, 0.0) p4 = gmsh.model.geo.addPoint(1.0, 0.5, 0.0) l0 = gmsh.model.geo.addLine(p0, p1) l1 = gmsh.model.geo.addCircleArc(p1, p4, p2) l2 = gmsh.model.geo.addLine(p2, p3) l3 = gmsh.model.geo.addLine(p3, p0) cl0 = gmsh.model.geo.addCurveLoop([l0, l1, l2, l3]) s0 = gmsh.model.geo.addPlaneSurface([cl0]) gmsh.model.addPhysicalGroup(1, [l0, l2], 2) gmsh.model.setPhysicalName(1, 2, "sides") gmsh.model.addPhysicalGroup(1, [l1], 3) gmsh.model.setPhysicalName(1, 3, "arc") gmsh.model.addPhysicalGroup(2, [s0], 4) gmsh.model.setPhysicalName(2, 4, "surface") gmsh.model.geo.synchronize() gmsh.model.mesh.generate() gmsh.model.mesh.setOrder(2) gmsh_model = gmsh.model else: gmsh_model = None mesh, mts = dolfiny.mesh.gmsh_to_dolfin(gmsh_model, 2, prune_z=True) mt1, keys1 = dolfiny.mesh.merge_meshtags(mts, 1) mt2, keys2 = dolfiny.mesh.merge_meshtags(mts, 2) assert mesh.geometry.dim == 2 assert mesh.topology.dim == 2 assert mts["arc"].dim == 1 with dolfinx.io.XDMFFile(MPI.COMM_WORLD, "mesh.xdmf", "w") as file: file.write_mesh(mesh) mesh.topology.create_connectivity(1, 2) file.write_meshtags(mts["arc"]) ds = ufl.Measure("ds", subdomain_data=mt1, domain=mesh) form = dolfinx.fem.form(1.0 * ds(keys1["sides"]) + 1.0 * ds(keys1["arc"])) val = dolfinx.fem.assemble_scalar(form) val = mesh.comm.allreduce(val, op=MPI.SUM) assert numpy.isclose(val, 2.0 + 2.0 * numpy.pi * 0.5 / 2.0, rtol=1.0e-3) dx = ufl.Measure("dx", subdomain_data=mt2, domain=mesh) form = dolfinx.fem.form(1.0 * dx(keys2["surface"])) val = dolfinx.fem.assemble_scalar(form) val = mesh.comm.allreduce(val, op=MPI.SUM) assert numpy.isclose(val, 1.0 + numpy.pi * 0.5**2 / 2.0, rtol=1.0e-3)
# Max inner ring velocity v_inner_max = 0.1 # [m/s] # Normal and tangential velocity at inner ring v_n = dolfinx.fem.Constant(mesh, 0.0) # [m/s] v_t = dolfinx.fem.Constant(mesh, 0.0) # [m/s] -- value set/updated in analysis # Global time time = dolfinx.fem.Constant(mesh, 0.0) # [s] # Time step size dt = dolfinx.fem.Constant(mesh, 0.05) # [s] # Number of time steps nT = 80 # Define integration measures dx = ufl.Measure("dx", domain=mesh, subdomain_data=subdomains, metadata={"quadrature_degree": 4}) ds = ufl.Measure("ds", domain=mesh, subdomain_data=interfaces, metadata={"quadrature_degree": 4}) # Inner ring velocity def v_inner_(t=0.0, vt=v_inner_max, g=5, a=1, b=3): return vt * 0.25 * (np.tanh(g * (t - a)) + 1) * (np.tanh(-g * (t - b)) + 1) # Function spaces Ve = ufl.VectorElement("CG", mesh.ufl_cell(), 2) Pe = ufl.FiniteElement("CG", mesh.ufl_cell(), 1)
def solve(self, f, filename): # redifine constans for specific frequency self.f = f self.omega = 2 * np.pi * f self.lmda = self.c / f self.k0 = self.omega / self.c # Load mesh mesh, cell_tags, facet_tags = read_from_msh(filename, cell_data=True, facet_data=True, gdim=2) # Define function space V = dolfinx.FunctionSpace(mesh, ("Lagrange", self.degree)) # Interpolate wavenumber k onto V k = dolfinx.Constant(V, self.k0) # Interpolate absorbing layer piece of wavenumber k_absorb onto V k_absorb = dolfinx.Function(V) adiabatic_layer = AdiabaticLayer(self.deg_absorber, self.k0, self.lmda) k_absorb.interpolate(adiabatic_layer.eval) # Interpolate incident wave field onto V ui = dolfinx.Function(V) ui_expr = IncidentWave(self.k0) ui.interpolate(ui_expr.eval) # Define variational problem u = ufl.TrialFunction(V) v = ufl.TestFunction(V) ds_exited = ufl.Measure("ds", domain=mesh, subdomain_data=facet_tags, subdomain_id=1) a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx \ - k ** 2 * ufl.inner(u, v) * ufl.dx \ - k_absorb * ufl.inner(u, v) * ufl.dx L = -1j * self.omega * self.rho_0 * ufl.inner(ui, v) * ufl.dx # Assemble matrix and vector and set up direct solver A = dolfinx.fem.assemble_matrix(a) A.assemble() b = dolfinx.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) solver = PETSc.KSP().create(mesh.mpi_comm()) opts = PETSc.Options() opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" opts["pc_factor_mat_solver_type"] = "mumps" solver.setFromOptions() solver.setOperators(A) # Solve linear system u = dolfinx.Function(V) start = time.time() solver.solve(b, u.vector) end = time.time() time_elapsed = end - start print('Solve time: ', time_elapsed) u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) save(mesh, u, f"../Solution/sol_{f}Hz.xdmf")
def test_assembly_ds_domains(mesh): V = dolfinx.FunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) def bottom(x): return numpy.isclose(x[1], 0.0) def top(x): return numpy.isclose(x[1], 1.0) def left(x): return numpy.isclose(x[0], 0.0) def right(x): return numpy.isclose(x[0], 1.0) bottom_facets = locate_entities_geometrical(mesh, mesh.topology.dim - 1, bottom, boundary_only=True) bottom_vals = numpy.full(bottom_facets.shape, 1, numpy.intc) top_facets = locate_entities_geometrical(mesh, mesh.topology.dim - 1, top, boundary_only=True) top_vals = numpy.full(top_facets.shape, 2, numpy.intc) left_facets = locate_entities_geometrical(mesh, mesh.topology.dim - 1, left, boundary_only=True) left_vals = numpy.full(left_facets.shape, 3, numpy.intc) right_facets = locate_entities_geometrical(mesh, mesh.topology.dim - 1, right, boundary_only=True) right_vals = numpy.full(right_facets.shape, 6, numpy.intc) indices = numpy.hstack( (bottom_facets, top_facets, left_facets, right_facets)) values = numpy.hstack((bottom_vals, top_vals, left_vals, right_vals)) indices, pos = numpy.unique(indices, return_index=True) marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim - 1, indices, values[pos]) ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh) w = dolfinx.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) # Assemble matrix a = w * ufl.inner(u, v) * (ds(1) + ds(2) + ds(3) + ds(6)) A = dolfinx.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * ds A2 = dolfinx.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # Assemble vector L = ufl.inner(w, v) * (ds(1) + ds(2) + ds(3) + ds(6)) b = dolfinx.fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) L2 = ufl.inner(w, v) * ds b2 = dolfinx.fem.assemble_vector(L2) b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # Assemble scalar L = w * (ds(1) + ds(2) + ds(3) + ds(6)) s = dolfinx.fem.assemble_scalar(L) s = mesh.mpi_comm().allreduce(s, op=MPI.SUM) L2 = w * ds s2 = dolfinx.fem.assemble_scalar(L2) s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM) assert (s == pytest.approx(s2, 1.0e-12) and 2.0 == pytest.approx(s, 1.0e-12))
def test_assembly_ds_domains(mode): mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 10, 10, ghost_mode=mode) V = dolfinx.FunctionSpace(mesh, ("CG", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) def bottom(x): return numpy.isclose(x[1], 0.0) def top(x): return numpy.isclose(x[1], 1.0) def left(x): return numpy.isclose(x[0], 0.0) def right(x): return numpy.isclose(x[0], 1.0) bottom_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, bottom) bottom_vals = numpy.full(bottom_facets.shape, 1, numpy.intc) top_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, top) top_vals = numpy.full(top_facets.shape, 2, numpy.intc) left_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, left) left_vals = numpy.full(left_facets.shape, 3, numpy.intc) right_facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, right) right_vals = numpy.full(right_facets.shape, 6, numpy.intc) indices = numpy.hstack((bottom_facets, top_facets, left_facets, right_facets)) values = numpy.hstack((bottom_vals, top_vals, left_vals, right_vals)) indices, pos = numpy.unique(indices, return_index=True) marker = dolfinx.mesh.MeshTags(mesh, mesh.topology.dim - 1, indices, values[pos]) ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh) w = dolfinx.Function(V) with w.vector.localForm() as w_local: w_local.set(0.5) bc = dolfinx.fem.DirichletBC(dolfinx.Function(V), range(30)) # Assemble matrix a = w * ufl.inner(u, v) * (ds(1) + ds(2) + ds(3) + ds(6)) A = dolfinx.fem.assemble_matrix(a) A.assemble() norm1 = A.norm() a2 = w * ufl.inner(u, v) * ds A2 = dolfinx.fem.assemble_matrix(a2) A2.assemble() norm2 = A2.norm() assert norm1 == pytest.approx(norm2, 1.0e-12) # Assemble vector L = ufl.inner(w, v) * (ds(1) + ds(2) + ds(3) + ds(6)) b = dolfinx.fem.assemble_vector(L) dolfinx.fem.apply_lifting(b, [a], [[bc]]) b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) dolfinx.fem.set_bc(b, [bc]) L2 = ufl.inner(w, v) * ds b2 = dolfinx.fem.assemble_vector(L2) dolfinx.fem.apply_lifting(b2, [a2], [[bc]]) b2.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) dolfinx.fem.set_bc(b2, [bc]) assert b.norm() == pytest.approx(b2.norm(), 1.0e-12) # Assemble scalar L = w * (ds(1) + ds(2) + ds(3) + ds(6)) s = dolfinx.fem.assemble_scalar(L) s = mesh.mpi_comm().allreduce(s, op=MPI.SUM) L2 = w * ds s2 = dolfinx.fem.assemble_scalar(L2) s2 = mesh.mpi_comm().allreduce(s2, op=MPI.SUM) assert (s == pytest.approx(s2, 1.0e-12) and 2.0 == pytest.approx(s, 1.0e-12))
def free_end(x): """Marks the leftmost points of the cantilever""" return numpy.isclose(x[0], 48.0) def left(x): """Marks left part of boundary, where cantilever is attached to wall""" return numpy.isclose(x[0], 0.0) # Locate all facets at the free end and assign them value 1 free_end_facets = locate_entities_boundary(mesh, 1, free_end) mt = dolfinx.mesh.MeshTags(mesh, 1, free_end_facets, 1) ds = ufl.Measure("ds", subdomain_data=mt) # Homogeneous boundary condition in displacement u_bc = dolfinx.Function(U) with u_bc.vector.localForm() as loc: loc.set(0.0) # Displacement BC is applied to the left side left_facets = locate_entities_boundary(mesh, 1, left) bdofs = locate_dofs_topological(U, 1, left_facets) bc = dolfinx.fem.DirichletBC(u_bc, bdofs) # Elastic stiffness tensor and Poisson ratio E, nu = 1.0, 1.0 / 3.0
alpha_ub.interpolate(lambda x: np.ones_like(x[0])) #In order to defined a function in a specific subspace of the model, it must be #specified in the model 'V_u.sub(i)', where i = 0 -> x, 1 -> y, 2-> z. #Don't forget to collapse, to choose only the DOF associated with the subspace. #I don't think this part works to definy the body force applied in a geometry. #It could be better to define it in the energy definition as constant. If not a #constant, we might need to define as a space function. # g = dolfinx.fem.Function(V_u, name="Body_pressure") # with g.vector.localForm() as loc: # loc.set(-78500.0) # Integral measures -> in order to define the energy lately, it's necessary to #define the integral measures, as such one is a integral. dx = ufl.Measure("dx", domain=mesh) #-> volume measure #We include here the subdomain data generated at the gmsh file. ds = ufl.Measure("ds", subdomain_data=facet_tags, domain=mesh) #-> surface measure #ds(<number of the facet tags>) #dS = ufl.Measure("dS", domain = mesh) - inner boundaries of the mesh -> not usefull import models from models import DamageElasticityModel as Brittle model = Brittle(parameters.get('model')) state = {'u': u, 'alpha': alpha} #The total energy density is calculated this time using a already written #function of the "model". This return the elasticity energy (with the a(alpha)) #and the damage energy term. To count for externals forces, it need to substract it #from the total energy