Esempio n. 1
0
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])
Esempio n. 3
0
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
Esempio n. 5
0
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
Esempio n. 6
0
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
Esempio n. 7
0
 def box(self, p1, p2, nx, ny, nz):
     return FEN.BoxMesh(FEN.Point(p1), FEN.Point(p2), nx, ny, nz)
Esempio n. 8
0
# 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
Esempio n. 11
0
# 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)