def MeshDefinition(Dimensions, NumberElements, Type='Lagrange', PolynomDegree=1): # Mesh Mesh = fe.BoxMesh(fe.Point(-Dimensions[0]/2, -Dimensions[1]/2, -Dimensions[2]/2), fe.Point(Dimensions[0]/2, Dimensions[1]/2, Dimensions[2]/2), NumberElements, NumberElements, NumberElements) # Functions spaces V_ele = fe.VectorElement(Type, Mesh.ufl_cell(), PolynomDegree) V = fe.VectorFunctionSpace(Mesh, Type, PolynomDegree) # Finite element functions du = fe.TrialFunction(V) v = fe.TestFunction(V) u = fe.Function(V) return [Mesh, V, u, du, v]
def setup_coarse_mesh(self): """ This creates the rectangular mesh, or rectangular prism in 3D. """ if len(self.mesh_size) == 2: self.mesh = fenics.RectangleMesh( fenics.mpi_comm_world(), fenics.Point(self.xmin, self.ymin), fenics.Point(self.xmax, self.ymax), self.mesh_size[0], self.mesh_size[1], "crossed") elif len(self.mesh_size) == 3: self.mesh = fenics.BoxMesh( fenics.mpi_comm_world(), fenics.Point(self.xmin, self.ymin, self.zmin), fenics.Point(self.xmax, self.ymax, self.zmax), self.mesh_size[0], self.mesh_size[1], self.mesh_size[2])
def get_mesh(length, nx, ny, nz=None): """获得 mesh """ if nz is None: mesh = fs.RectangleMesh(fs.Point(0.0, 0.0), fs.Point(length, length), nx, ny) else: mesh = fs.BoxMesh( fs.Point(0.0, 0.0, 0.0), fs.Point(length, length, length), nx, ny, nz, ) return mesh
def test_minexample(): import scipy.integrate import fenics as fe import numpy as np import magnics # Material parameters Ms = 8.6e5 # saturation magnetisation (A/m) alpha = 0.1 # Gilbert damping gamma = 2.211e5 # gyromagnetic ratio A = 1e-11 # exchange constant (J/m) #A = 0 D = 0*1.58e-3 # DMI constant (FeGe: D = 1.58e-3 J/m²) K = 0*5e3 # anisotropy constant (Co: K = 4.5e5 J/m³) # External magnetic field. B = 0.1 # (T) mu0 = 4 * np.pi * 1e-7 # vacuum permeability # Zeeman field H = Ms / 2 * fe.Constant((0,0,1)) # easy axis ea = fe.Constant((0,1,1)) # mesh parameters d = 100e-9 thickness = 100e-9 nx = ny = 20 nz = 10 # create mesh p1 = fe.Point(0, 0, 0) p2 = fe.Point(d, d, thickness) mesh = fe.BoxMesh(p1, p2, nx, ny, nz) m, Heff, u, v, V = magnics.vectorspace(mesh) def effective_field(m, volume=None): w_Zeeman = - mu0 * Ms * fe.dot(m, H) w_exchange = A * fe.inner(fe.grad(m), fe.grad(m)) w_DMI = D * fe.inner(m, fe.curl(m)) w_ani = - K * fe.inner(m, ea)**2 w = w_Zeeman + w_exchange + w_DMI + w_ani return -1/(mu0*Ms) * fe.derivative(w*fe.dx, m) # Effective field Heff_form = effective_field(m) # Preassemble projection Matrix Amat = fe.assemble(fe.dot(u, v)*fe.dx) LU = fe.LUSolver() LU.set_operator(Amat) def compute_dmdt(m): """Convenience function that does all in one go""" # Assemble RHS b = fe.assemble(Heff_form) # Project onto Heff LU.solve(Heff.vector(), b) LLG = -gamma/(1+alpha*alpha)*fe.cross(m, Heff) - alpha*gamma/(1+alpha*alpha)*fe.cross(m, fe.cross(m, Heff)) result = fe.assemble(fe.dot(LLG, v)*fe.dP) return result.array() # function for integration of system of ODEs def rhs_micromagnetic(m_vector_array, t, counter=[0]): assert isinstance(m_vector_array, np.ndarray) m.vector()[:] = m_vector_array[:] dmdt = compute_dmdt(m) return dmdt m_init = fe.Constant((1, 0, 0)) m = fe.interpolate(m_init, V) ts = np.linspace(0, 1e-11, 100) # empty call of time integrator, just to get FEniCS to cache all forms etc rhs_micromagnetic(m.vector().array(), 0) ms = scipy.integrate.odeint(rhs_micromagnetic, y0=m.vector().array(), t=ts, rtol=1e-10, atol=1e-10) def macrospin_analytic_solution(alpha, gamma, H, t_array): """ Computes the analytic solution of magnetisation x component as a function of time for the macrospin in applied external magnetic field H. Source: PhD Thesis Matteo Franchin, http://eprints.soton.ac.uk/161207/1.hasCoversheetVersion/thesis.pdf, Appendix B, page 127 """ t0 = 1 / (gamma * alpha * H) * np.log(np.sin(np.pi / 2) / \ (1 + np.cos(np.pi / 2))) mx_analytic = [] for t in t_array: phi = gamma * H * t # (B16) costheta = np.tanh(gamma * alpha * H * (t - t0)) # (B17) sintheta = 1 / np.cosh(gamma * alpha * H * (t - t0)) # (B18) mx_analytic.append(sintheta * np.cos(phi)) return np.array(mx_analytic) mx_analytic = macrospin_analytic_solution(alpha, gamma, Ms/2, ts) tmp2 = ms[:,0:1] # might be m_x, m_y, m_z of first vector difference = tmp2[:,0] - mx_analytic print("max deviation: {}".format(max(abs(difference)))) # add quick test eps = 0.01 #ref = 0.0655908475021 # for tmax = 1e-10 ref = 0.0422068879247 # for tmax = 5e-11 ref = 0.00765261606231 # for tmax = 1e-11 assert ref - eps < max(abs(difference)) < ref + eps
def regular_box_mesh(n=10, S_x=0.0, S_y=0.0, S_z=None, E_x=1.0, E_y=1.0, E_z=None): r"""Creates a mesh corresponding to a rectangle or cube. This function creates a uniform mesh of either a rectangle or a cube, with specified start (``S_``) and end points (``E_``). The resulting mesh uses ``n`` elements along the shortest direction and accordingly many along the longer ones. The resulting domain is .. math:: \begin{alignedat}{2} &[S_x, E_x] \times [S_y, E_y] \quad &&\text{ in } 2D, \\ &[S_x, E_x] \times [S_y, E_y] \times [S_z, E_z] \quad &&\text{ in } 3D. \end{alignedat} The boundary markers are ordered as follows: - 1 corresponds to :math:`x=S_x`. - 2 corresponds to :math:`x=E_x`. - 3 corresponds to :math:`y=S_y`. - 4 corresponds to :math:`y=E_y`. - 5 corresponds to :math:`z=S_z` (only in 3D). - 6 corresponds to :math:`z=E_z` (only in 3D). Parameters ---------- n : int Number of elements in the shortest coordinate direction. S_x : float Start of the x-interval. S_y : float Start of the y-interval. S_z : float or None, optional Start of the z-interval, mesh is 2D if this is ``None`` (default is ``None``). E_x : float End of the x-interval. E_y : float End of the y-interval. E_z : float or None, optional End of the z-interval, mesh is 2D if this is ``None`` (default is ``None``). Returns ------- mesh : dolfin.cpp.mesh.Mesh The computational mesh. subdomains : dolfin.cpp.mesh.MeshFunctionSizet A MeshFunction object containing the subdomains. boundaries : dolfin.cpp.mesh.MeshFunctionSizet A MeshFunction object containing the boundaries. dx : ufl.measure.Measure The volume measure of the mesh corresponding to subdomains. ds : ufl.measure.Measure The surface measure of the mesh corresponding to boundaries. dS : ufl.measure.Measure The interior facet measure of the mesh corresponding to boundaries. """ n = int(n) if not n > 0: raise InputError('cashocs.geometry.regular_box_mesh', 'n', 'This needs to be positive.') if not S_x < E_x: raise InputError( 'cashocs.geometry.regular_box_mesh', 'S_x', 'Incorrect input for the x-coordinate. S_x has to be smaller than E_x.' ) if not S_y < E_y: raise InputError( 'cashocs.geometry.regular_box_mesh', 'S_y', 'Incorrect input for the y-coordinate. S_y has to be smaller than E_y.' ) if not ((S_z is None and E_z is None) or (S_z < E_z)): raise InputError( 'cashocs.geometry.regular_box_mesh', 'S_z', 'Incorrect input for the z-coordinate. S_z has to be smaller than E_z, or only one of them is specified.' ) if S_z is None: lx = E_x - S_x ly = E_y - S_y sizes = [lx, ly] dim = 2 else: lx = E_x - S_x ly = E_y - S_y lz = E_z - S_z sizes = [lx, ly, lz] dim = 3 size_min = np.min(sizes) num_points = [int(np.round(length / size_min * n)) for length in sizes] if S_z is None: mesh = fenics.RectangleMesh(fenics.Point(S_x, S_y), fenics.Point(E_x, E_y), num_points[0], num_points[1]) else: mesh = fenics.BoxMesh(fenics.Point(S_x, S_y, S_z), fenics.Point(E_x, E_y, E_z), num_points[0], num_points[1], num_points[2]) subdomains = fenics.MeshFunction('size_t', mesh, dim=dim) boundaries = fenics.MeshFunction('size_t', mesh, dim=dim - 1) x_min = fenics.CompiledSubDomain('on_boundary && near(x[0], sx, tol)', tol=fenics.DOLFIN_EPS, sx=S_x) x_max = fenics.CompiledSubDomain('on_boundary && near(x[0], ex, tol)', tol=fenics.DOLFIN_EPS, ex=E_x) x_min.mark(boundaries, 1) x_max.mark(boundaries, 2) y_min = fenics.CompiledSubDomain('on_boundary && near(x[1], sy, tol)', tol=fenics.DOLFIN_EPS, sy=S_y) y_max = fenics.CompiledSubDomain('on_boundary && near(x[1], ey, tol)', tol=fenics.DOLFIN_EPS, ey=E_y) y_min.mark(boundaries, 3) y_max.mark(boundaries, 4) if S_z is not None: z_min = fenics.CompiledSubDomain('on_boundary && near(x[2], sz, tol)', tol=fenics.DOLFIN_EPS, sz=S_z) z_max = fenics.CompiledSubDomain('on_boundary && near(x[2], ez, tol)', tol=fenics.DOLFIN_EPS, ez=E_z) z_min.mark(boundaries, 5) z_max.mark(boundaries, 6) dx = fenics.Measure('dx', mesh, subdomain_data=subdomains) ds = fenics.Measure('ds', mesh, subdomain_data=boundaries) dS = fenics.Measure('dS', mesh) return mesh, subdomains, boundaries, dx, ds, dS
def regular_mesh(n=10, L_x=1.0, L_y=1.0, L_z=None): r"""Creates a mesh corresponding to a rectangle or cube. This function creates a uniform mesh of either a rectangle or a cube, starting at the origin and having length specified in ``L_x``, ``L_y``, and ``L_z``. The resulting mesh uses ``n`` elements along the shortest direction and accordingly many along the longer ones. The resulting domain is .. math:: \begin{alignedat}{2} &[0, L_x] \times [0, L_y] \quad &&\text{ in } 2D, \\ &[0, L_x] \times [0, L_y] \times [0, L_z] \quad &&\text{ in } 3D. \end{alignedat} The boundary markers are ordered as follows: - 1 corresponds to :math:`x=0`. - 2 corresponds to :math:`x=L_x`. - 3 corresponds to :math:`y=0`. - 4 corresponds to :math:`y=L_y`. - 5 corresponds to :math:`z=0` (only in 3D). - 6 corresponds to :math:`z=L_z` (only in 3D). Parameters ---------- n : int Number of elements in the shortest coordinate direction. L_x : float Length in x-direction. L_y : float Length in y-direction. L_z : float or None, optional Length in z-direction, if this is ``None``, then the geometry will be two-dimensional (default is ``None``). Returns ------- mesh : dolfin.cpp.mesh.Mesh The computational mesh. subdomains : dolfin.cpp.mesh.MeshFunctionSizet A :py:class:`fenics.MeshFunction` object containing the subdomains. boundaries : dolfin.cpp.mesh.MeshFunctionSizet A MeshFunction object containing the boundaries. dx : ufl.measure.Measure The volume measure of the mesh corresponding to subdomains. ds : ufl.measure.Measure The surface measure of the mesh corresponding to boundaries. dS : ufl.measure.Measure The interior facet measure of the mesh corresponding to boundaries. """ if not n > 0: raise InputError('cashocs.geometry.regular_mesh', 'n', 'This needs to be positive.') if not L_x > 0.0: raise InputError('cashocs.geometry.regular_mesh', 'L_x', 'L_x needs to be positive') if not L_y > 0.0: raise InputError('cashocs.geometry.regular_mesh', 'L_y', 'L_y needs to be positive') if not (L_z is None or L_z > 0.0): raise InputError('cashocs.geometry.regular_mesh', 'L_z', 'L_z needs to be positive or None (for 2D mesh)') n = int(n) if L_z is None: sizes = [L_x, L_y] dim = 2 else: sizes = [L_x, L_y, L_z] dim = 3 size_min = np.min(sizes) num_points = [int(np.round(length / size_min * n)) for length in sizes] if L_z is None: mesh = fenics.RectangleMesh(fenics.Point(0, 0), fenics.Point(sizes), num_points[0], num_points[1]) else: mesh = fenics.BoxMesh(fenics.Point(0, 0, 0), fenics.Point(sizes), num_points[0], num_points[1], num_points[2]) subdomains = fenics.MeshFunction('size_t', mesh, dim=dim) boundaries = fenics.MeshFunction('size_t', mesh, dim=dim - 1) x_min = fenics.CompiledSubDomain('on_boundary && near(x[0], 0, tol)', tol=fenics.DOLFIN_EPS) x_max = fenics.CompiledSubDomain('on_boundary && near(x[0], length, tol)', tol=fenics.DOLFIN_EPS, length=sizes[0]) x_min.mark(boundaries, 1) x_max.mark(boundaries, 2) y_min = fenics.CompiledSubDomain('on_boundary && near(x[1], 0, tol)', tol=fenics.DOLFIN_EPS) y_max = fenics.CompiledSubDomain('on_boundary && near(x[1], length, tol)', tol=fenics.DOLFIN_EPS, length=sizes[1]) y_min.mark(boundaries, 3) y_max.mark(boundaries, 4) if L_z is not None: z_min = fenics.CompiledSubDomain('on_boundary && near(x[2], 0, tol)', tol=fenics.DOLFIN_EPS) z_max = fenics.CompiledSubDomain( 'on_boundary && near(x[2], length, tol)', tol=fenics.DOLFIN_EPS, length=sizes[2]) z_min.mark(boundaries, 5) z_max.mark(boundaries, 6) dx = fenics.Measure('dx', mesh, subdomain_data=subdomains) ds = fenics.Measure('ds', mesh, subdomain_data=boundaries) dS = fenics.Measure('dS', mesh) return mesh, subdomains, boundaries, dx, ds, dS
def box(self, p1, p2, nx, ny, nz): return FEN.BoxMesh(FEN.Point(p1), FEN.Point(p2), nx, ny, nz)
# import import fenics as fn # set parameters fn.parameters["form_compiler"]["representation"] = "uflacs" fn.parameters["form_compiler"]["cpp_optimize"] = True # create mesh and function spaces L = 50.0 mesh = fn.BoxMesh( fn.Point(-L, 0.0, -L), fn.Point(L, 2*L, L), 20, 5, 20) nn = fn.FacetNormal(mesh) Vh = fn.VectorElement("CG", mesh.ufl_cell(), 2) Zh = fn.FiniteElement("CG", mesh.ufl_cell(), 1) Qh = fn.FiniteElement("CG", mesh.ufl_cell(), 2) Hh = fn.FunctionSpace(mesh, fn.MixedElement([Vh, Zh, Qh])) # variables to solve for, and test functions u, phi, p = fn.TrialFunctions(Hh) v, psi, q = fn.TestFunctions(Hh) # file output fileU = fn.File(mesh.mpi_comm(), "Output/2_5_2_Footing_3D/u.pvd") filePHI = fn.File(mesh.mpi_comm(), "Output/2_5_2_Footing_3D/phi.pvd") fileP = fn.File(mesh.mpi_comm(), "Output/2_5_2_Footing_3D/p.pvd") # constants
import fenics as fs import matplotlib.pyplot as plt # scaled variables L = 1 W = 0.2 mu = 1 rho = 1 delta = W / L gamma = 0.4 * delta**2 beta = 1.25 lambda_ = beta g = gamma # Create mesh and define function space mesh = fs.BoxMesh(fs.Point(0, 0, 0), fs.Point(L, W, W), 10, 3, 3) V = fs.VectorFunctionSpace(mesh, 'P', 1) # define boundary condition tol = 1e-14 def clamped_boundary(x, on_boundary): return on_boundary and x[0] < tol bc = fs.DirichletBC(V, fs.Constant((0, 0, 0)), clamped_boundary) # define strain and stress def epsilon(u):
def melt_pcm_3d(m=(10, 10, 1), dt=1.e-3, initial_pci_refinement_cycles=2, max_pci_refinement_cycles_per_time=6, output_dir='output/melt_pcm_3d', start_time=0., end_time=0.05, nlp_divergence_threshold=1.e12, nlp_max_iterations=50, restart=False, restart_filepath=''): theta_hot = 1. theta_cold = -0.1 w, mesh = phaseflow.run( Ste=1., Ra=1., Pr=1., mu_s=1.e4, mu_l=1., g=(0., -1., 0.), mesh=fenics.BoxMesh(fenics.Point(0., 0., -0.2), fenics.Point(1., 1., 0.2), m[0], m[1], m[2]), time_step_bounds=dt, start_time=start_time, end_time=end_time, stop_when_steady=True, regularization={ 'T_f': 0.1, 'r': 0.05 }, initial_pci_refinement_cycles=initial_pci_refinement_cycles, max_pci_refinement_cycles_per_time=max_pci_refinement_cycles_per_time, minimum_cell_diameter=0.01, nlp_max_iterations=nlp_max_iterations, nlp_divergence_threshold=nlp_divergence_threshold, initial_values_expression=("0.", "0.", "0.", "0.", "(" + str(theta_hot) + " - " + str(theta_cold) + ")*(x[0] < 0.001) + " + str(theta_cold)), boundary_conditions=[{ 'subspace': 0, 'value_expression': ("0.", "0.", "0."), 'degree': 3, 'location_expression': "near(x[0], 0.) | near(x[0], 1.) | near(x[1], 0.) | near(x[1], 1.) | near(x[2], -0.2) | near(x[2], 0.2)", 'method': "topological" }, { 'subspace': 2, 'value_expression': str(theta_hot), 'degree': 2, 'location_expression': "near(x[0], 0.)", 'method': "topological" }, { 'subspace': 2, 'value_expression': str(theta_cold), 'degree': 2, 'location_expression': "near(x[0], 1.)", 'method': "topological" }], output_dir=output_dir, debug=True, restart=restart, restart_filepath=restart_filepath) return w, mesh
# Zeeman field H = Ms / 2 * fe.Constant((0, 0, 1)) # easy axis ea = fe.Constant((0, 1, 1)) # mesh parameters d = 100e-9 thickness = 100e-9 nx = ny = 20 nz = 10 # create mesh p1 = fe.Point(0, 0, 0) p2 = fe.Point(d, d, thickness) mesh = fe.BoxMesh(p1, p2, nx, ny, nz) m, Heff, u, v, V = setup_vectorspace(mesh) def effective_field(m, volume=None): w_Zeeman = -mu0 * Ms * fe.dot(m, H) w_exchange = A * fe.inner(fe.grad(m), fe.grad(m)) w_DMI = D * fe.inner(m, fe.curl(m)) w_ani = -K * fe.inner(m, ea)**2 w = w_Zeeman + w_exchange + w_DMI + w_ani return -1 / (mu0 * Ms) * fe.derivative(w * fe.dx, m) m_init = fe.Constant((1, 0, 0)) m = fe.interpolate(m_init, V)