def solve_poisson_equation(u_e, alpha, title_name): domain = Circle(Point(0, 0), 1) mesh = generate_mesh(domain, 30) V = FunctionSpace(mesh, 'P', 2) u_d = Expression(ccode(u_e), degree=2) bc = DirichletBC(V, u_d, check_boundary) u = TrialFunction(V) v = TestFunction(V) f = -calculate_laplacian(u_e) + alpha * u_e f = Expression(ccode(f), degree=2) g = calculate_normal_derivative(u_e) g = Expression(ccode(g), degree=2) a = dot(grad(u), grad(v)) * dx + alpha * u * v * dx L = f * v * dx + g * v * ds u = Function(V) solve(a == L, u, bc) u_e = u_d error_L2 = errornorm(u_e, u, 'L2') vertex_values_u = u.compute_vertex_values(mesh) vertex_values_u_e = u_e.compute_vertex_values(mesh) error_max = np.max(np.abs(vertex_values_u_e - vertex_values_u)) print('Max error = %.3g, L2 error = %.3g' % (error_max, error_L2)) image = plot_solutions(u_e, u, mesh) imageio.imsave(f'poisson_{title_name}.png', image)
def build_mesh(self, resolution=20): from mshr import Rectangle, Circle, generate_mesh domain = Rectangle(Point(0.0, 0.0), Point(self.L, self.L)) - Circle( Point(0.0, 0.0), self.radius ) return generate_mesh(domain, resolution)
def spherical_shell(dim, radii, n_refinements=0): """ Creates the mesh of a spherical shell using the mshr module. """ assert isinstance(dim, int) assert dim == 2 or dim == 3 assert isinstance(radii, (list, tuple)) and len(radii) == 2 ri, ro = radii assert isinstance(ri, float) and ri > 0. assert isinstance(ro, float) and ro > 0. assert ri < ro assert isinstance(n_refinements, int) and n_refinements >= 0 # mesh generation if dim == 2: center = dlfn.Point(0., 0.) elif dim == 3: center = dlfn.Point(0., 0., 0.) if dim == 2: domain = Circle(center, ro)\ - Circle(center, ri) mesh = generate_mesh(domain, 75) elif dim == 3: domain = Sphere(center, ro) \ - Sphere(center, ri) mesh = generate_mesh(domain, 15) # mesh refinement for i in range(n_refinements): mesh = dlfn.refine(mesh) # MeshFunction for boundaries ids facet_marker = dlfn.MeshFunction("size_t", mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # mark boundaries BoundaryMarkers = SphericalAnnulusBoundaryMarkers gamma_inner = CircularBoundary(mesh=mesh, radius=ri) gamma_inner.mark(facet_marker, BoundaryMarkers.interior_boundary.value) gamma_outer = CircularBoundary(mesh=mesh, radius=ro) gamma_outer.mark(facet_marker, BoundaryMarkers.exterior_boundary.value) return mesh, facet_marker
def solve_heat_equation(u_e, steps_number, alpha, title_name): domain = Circle(Point(0, 0), 1) mesh = generate_mesh(domain, 30) V = FunctionSpace(mesh, 'P', 2) u_d = Expression(ccode(u_e), t=0, degree=2) bc = DirichletBC(V, u_d, check_boundary) u_n = interpolate(u_d, V) u = TrialFunction(V) v = TestFunction(V) t = symbols('t') f = diff(u_e, t) - alpha * calculate_laplacian(u_e) f = Expression(ccode(f), t=0, degree=2) g = calculate_normal_derivative(u_e) g = Expression(ccode(g), t=0, degree=2) T = 5.0 dt = T / steps_number a = u * v * dx + dt * dot(grad(u), grad(v)) * dx L = (u_n + dt * f) * v * dx + dt * v * g * ds u = Function(V) t = 0 plots = [] errors_L2 = [] errors_max = [] for n in range(steps_number): t += dt u_d.t = t g.t = t f.t = t solve(a == L, u, bc) u_n.assign(u) u_e = interpolate(u_d, V) error_L2 = errornorm(u_e, u, 'L2') error_max = np.abs(u_e.vector().get_local() - u.vector().get_local()).max() print('t = %.2f: max error = %.3g, L2 error = %.3g' % (t, error_max, error_L2)) plots.append(plot_solutions(u_e, u, mesh)) errors_max.append(error_max) errors_L2.append(error_L2) imageio.imsave(f'heat_{title_name}.png', plots[-1]) write_video(plots, f'heat_{title_name}') time_interval = np.linspace(dt, T, steps_number) plt.plot(time_interval, errors_max, label='Max error') plt.plot(time_interval, errors_L2, label='L2 error') plt.legend() plt.savefig(f'errors_{title_name}.png') plt.close()
def generate2DIdealizedBrainMesh(config): from mshr import Circle, Rectangle, generate_mesh ids = {dom["name"]:dom["id"] for dom in config["domains"]} N = 1/config["h"] N = config["N"] # brain_radius = config["brain_radius"] # 0.1 sas_radius = config["sas_radius"] # brain_radius*1.2 ventricle_radius = config["ventricle_radius"] # 0.03 aqueduct_width = config["aqueduct_width"] # 0.005 canal_width = config["canal_width"] # 0.02 canal_length = config["canal_length"] # 0.2 path = f"../meshes/ideal_brain_2D_N{N}/ideal_brain_2D_N{N}" os.popen(f'mkdir -p {path}') brain = Circle(Point(0,0), brain_radius) ventricle = Circle(Point(0,0), ventricle_radius) aqueduct = Rectangle(Point(-aqueduct_width/2, -brain_radius), Point(aqueduct_width/2, 0)) brain = brain - ventricle - aqueduct spinal_canal = Rectangle(Point(-canal_width/2, -canal_length), Point(canal_width/2, 0)) fluid = Circle(Point(0,0), sas_radius) + spinal_canal domain = fluid + brain domain.set_subdomain(ids["csf"], fluid) domain.set_subdomain(ids["parenchyma"], brain) domain.set_subdomain(ids["aqueduct"], aqueduct) domain.set_subdomain(ids["ventricle"], ventricle) mesh = generate_mesh(domain, N) subdomains = MeshFunction("size_t", mesh, 2, mesh.domains()) subdomains.rename("subdomains", "subdomains") subdomains_outfile = XDMFFile(path + "_labels.xdmf") subdomains_outfile.write(subdomains) subdomains_outfile.close() return path
""" FEniCS tutorial demo program: Deflection of a membrane. -Laplace(w) = p in the unit circle w = 0 on the boundary The load p is a Gaussian function centered at (0, 0.6). """ from fenics import * from mshr import Circle, generate_mesh # Create mesh and define function space domain = Circle(Point(0, 0), 1) mesh = generate_mesh(domain, 64) V = FunctionSpace(mesh, 'P', 2) w_D = Constant(0) def boundary(x, on_boundary): return on_boundary bc = DirichletBC(V, w_D, boundary) # Define load p = Expression('4*exp(-pow(beta, 2)*(pow(x[0], 2) + pow(x[1] - R0, 2)))', degree=1, beta=8, R0=0.6) # Define variational problem
def setup_geometry(interior_circle=True, num_mesh_refinements=0): # Generate mesh xmin, xmax = 0.0, 4.0 ymin, ymax = 0.0, 1.0 mesh_resolution = 30 geometry1 = Rectangle(Point(xmin, ymin), Point(xmax, ymax)) center = Point(0.5, 0.5) r = 0.1 side_length = 0.1 if interior_circle: geometry2 = Circle(center, r) else: l2 = side_length / 2 geometry2 = Rectangle(Point(center[0] - l2, center[1] - l2), Point(center[0] + l2, center[1] + l2)) mesh = generate_mesh(geometry1 - geometry2, mesh_resolution) # Refine mesh around the interior boundary for i in range(0, num_mesh_refinements): cell_markers = MeshFunction("bool", mesh, mesh.topology().dim()) for c in cells(mesh): p = c.midpoint() cell_markers[c] = (abs(p[0] - .5) < .5 and abs(p[1] - .5) < .3 and c.diameter() > .1) or c.diameter() > .2 mesh = refine(mesh, cell_markers) # Mark regions for boundary conditions eps = 1e-5 # Part of the boundary with zero pressure om = Expression("x[0] > XMAX - eps ? 1. : 0.", XMAX=xmax, eps=eps, degree=1) # Part of the boundary with prescribed velocity im = Expression("x[0] < XMIN + eps ? 1. : 0.", XMIN=xmin, eps=eps, degree=1) # Part of the boundary with zero velocity nm = Expression("x[0] > XMIN + eps && x[0] < XMAX - eps ? 1. : 0.", XMIN=xmin, XMAX=xmax, eps=eps, degree=1) # Define interior boundary class InteriorBoundary(SubDomain): def inside(self, x, on_boundary): # Compute squared distance to interior object midpoint d2 = (x[0] - center[0])**2 + (x[1] - center[1])**2 return on_boundary and d2 < (2 * r)**2 # Create mesh function over the cell facets sub_domains = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) # Mark all facets as sub domain 0 sub_domains.set_all(0) # Mark interior boundary facets as sub domain 1 interior_boundary = InteriorBoundary() interior_boundary.mark(sub_domains, 1) return mesh, om, im, nm, ymax, sub_domains
from dolfin import * from mshr import Circle, generate_mesh from vtkplotter.dolfin import plot, printc, Latex # Credits: # https://github.com/pf4d/fenics_scripts/blob/master/pi_estimate.py domain = Circle(Point(0.0, 0.0), 1.0) for res in [2**k for k in range(7)]: mesh = generate_mesh(domain, res) A = assemble(Constant(1) * dx(domain=mesh)) printc("resolution = %i, \t A-pi = %.5e" % (res, A - pi)) printc('~pi is about', A, c='yellow') l = Latex(r'\mathrm{Area}(r)=\pi=\int\int_D 1 \cdot d(x,y)', s=0.3) l.crop(0.3, 0.3).z(0.1) # crop invisible top and bottom and set at z=0.1 plot(mesh, l, alpha=0.4, style=1, axes=3)
def mesh(Nx, **params): circle = Circle(Point(0., 0.), 0.5) mesh = generate_mesh(circle, Nx) return mesh
u1.assign(u) print( time.strftime("\nElapsed time %H:%M:%S", time.gmtime(time.time() - start_time))) return u if __name__ == "__main__": ot, dt, nt = 0., 5e-4, 1001 t = ot + np.arange(nt) * dt print('Computing wavefields over dolfin mesh') mesh = Mesh("../meshes/dolfin_fine.xml.gz") u = awefem(mesh, t, source_loc=Point(0.8, 0.8), filename='dolfin/data/dolfin.pvd') print('Computing wavefields over unit square') mesh = UnitSquareMesh(100, 100) u = awefem(mesh, t, filename='square/data/square.pvd') print('Computing wavefields over unit circle') domain = Circle(Point(0., 0.), 1) mesh = generate_mesh(domain, 50) u = awefem(mesh, t, source_time_function=sine_source, filename='circle/data/circle.pvd')
from utils import plot_mesh, exact_kepler from mshr import Circle, generate_mesh from sympy2fenics import sympy2exp # exact kepler orbit H = -1.5 L = 0.5 (q0, p0, _, S, (c, a, b), _, _) = exact_kepler(H, L) # symbolic computation for the jacobi metric for schwarzschild geodesics x, y = sympy.var('x[0], x[1]') E, m, M = sympy.var('E, m, M') r = sympy.sqrt(x * x + y * y) g = E**2 - m**2 + 2 * M * m**2 / r f = 1 / (1 - 2 * M / r) ds = f * g / r**2 * sympy.Matrix( ((f * x**2 + y**2, (f - 1) * x * y), ((f - 1) * x * y, x**2 + f * y**2))) # choose parameters so that the schwarzschild solution is close to the kelper # the most import parameter is M. M = 0.0025 m = 1.0 / M**0.5 E = (2.0 * H + m**2)**0.5 gexp = Expression(sympy2exp(ds), E=E, m=m, M=M, degree=8) # build a large enough domain domain = Circle(Point(c), b + 0.45) mesh = generate_mesh(domain, 32) g = interpolate(gexp, FunctionSpace(mesh, "Regge", 1)) File("plots/schwarzschild_jacobi_metric.pvd") << g
def spherical_shell(dim, radii, boundary_ids, n_refinements=0): assert isinstance(dim, int) assert dim == 2 or dim == 3 assert isinstance(radii, (list, tuple)) and len(radii) == 2 ri, ro = radii assert isinstance(ri, float) and ri > 0. assert isinstance(ro, float) and ro > 0. assert ri < ro assert isinstance(boundary_ids, (list, tuple)) and len(boundary_ids) == 2 inner_boundary_id, outer_boundary_id = boundary_ids assert isinstance(inner_boundary_id, int) and inner_boundary_id >= 0 assert isinstance(outer_boundary_id, int) and outer_boundary_id >= 0 assert inner_boundary_id != outer_boundary_id assert isinstance(n_refinements, int) and n_refinements >= 0 # mesh generation from dolfin import Point if dim == 2: center = Point(0., 0.) elif dim == 3: center = Point(0., 0., 0.) from mshr import Sphere, Circle, generate_mesh if dim == 2: domain = Circle(center, ro) \ - Circle(center, ri) mesh = generate_mesh(domain, 75) elif dim == 3: domain = Sphere(center, ro) \ - Sphere(center, ri) mesh = generate_mesh(domain, 15) # mesh refinement from dolfin import refine for i in range(n_refinements): mesh = refine(mesh) # subdomains for boundaries from dolfin import MeshFunctionSizet facet_marker = MeshFunctionSizet(mesh, mesh.topology().dim() - 1) facet_marker.set_all(0) # size of smallest element hmin = mesh.hmin() # inner circle boundary class InnerCircle(SubDomain): def inside(self, x, on_boundary): # tolerance: half length of smallest element tol = hmin / 2. from math import sqrt if dim == 2: result = abs(sqrt(x[0]**2 + x[1]**2) - ri) < tol elif dim == 3: result = abs(sqrt(x[0]**2 + x[1]**2 + x[2]**2) - ri) < tol return result and on_boundary # outer cirlce boundary class OuterCircle(SubDomain): def inside(self, x, on_boundary): # tolerance: half length of smallest element tol = hmin / 2. from math import sqrt if dim == 2: result = abs(sqrt(x[0]**2 + x[1]**2) - ro) < tol elif dim == 3: result = abs(sqrt(x[0]**2 + x[1]**2 + x[2]**2) - ro) < tol return result and on_boundary # mark boundaries gamma_inner = InnerCircle() gamma_inner.mark(facet_marker, inner_boundary_id) gamma_outer = OuterCircle() gamma_outer.mark(facet_marker, outer_boundary_id) return mesh, facet_marker
def setup_geometry(geometry, finesse): ''' Setup different geometries. ''' if geometry == 'centered_cylinders': tol = 0.02 # tolerance for boundary definition radii = [2.0, 0.5] class Outer_circle(SubDomain): def inside(self, x, on_boundary): r = math.sqrt(x[0] * x[0] + x[1] * x[1]) return near(r, radii[0], tol) class Inner_circle(SubDomain): def inside(self, x, on_boundary): r = math.sqrt(x[0] * x[0] + x[1] * x[1]) return near(r, radii[1], tol) outer_circle = Outer_circle() inner_circle = Inner_circle() circ_large = Circle(Point(0, 0), radii[0]) circ_small = Circle(Point(0, 0), radii[1]) domain = circ_large - circ_small mesh = generate_mesh(domain, finesse) boundaries = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) boundaries.set_all(0) outer_circle.mark(boundaries, 1) inner_circle.mark(boundaries, 2) return mesh, boundaries elif geometry == 'centered_Lshape': tol = 0.02 # tolerance for boundary definition class Hor1(SubDomain): def inside(self, x, on_boundary): return near(x[1], 1) class Vert1(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0.5) and x[1] >= 0.5 class Hor2(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0.5) and x[0] <= 0.5 class Vert2(SubDomain): def inside(self, x, on_boundary): return near(x[0], 0) class Bottom(SubDomain): def inside(self, x, on_boundary): return near(x[1], 0) class Right(SubDomain): def inside(self, x, on_boundary): return near(x[0], 1) hor1 = Hor1() hor2 = Hor2() vert1 = Vert1() vert2 = Vert2() bottom = Bottom() right = Right() rectangle_large = Rectangle(Point(0, 0), Point(1, 1)) rectangle_small = Rectangle(Point(0, 1), Point(0.5, 0.5)) domain = rectangle_large - rectangle_small mesh = generate_mesh(domain, finesse) boundaries = MeshFunction('size_t', mesh, mesh.topology().dim() - 1) boundaries.set_all(0) hor1.mark(boundaries, 1) vert1.mark(boundaries, 1) hor2.mark(boundaries, 2) vert2.mark(boundaries, 2) bottom.mark(boundaries, 3) right.mark(boundaries, 4) return mesh, boundaries else: raise NotImplementedError
def CircleMesh(p, r, s): """ mshr has no CircleMesh. """ return generate_mesh(Circle(p, r, max(int(4 * pi / s), 4)), int(2 / s))