<jupyter_start><jupyter_text>![OpenDreamKit logo and EU Flag](header.png)OpenDreamKit review meeting 26 April 2017, Brussels Micromagnetic standard problem 3 Problem specificationThis problem is to calculate a single domain limit of a cubic magnetic particle. This is the size $L$ of equal energy for the so-called flower state (which one may also call a splayed state or a modified single-domain state) on the one hand, and the vortex or curling state on the other hand.Geometry:A cube with edge length, $L$, expressed in units of the intrinsic length scale, $l_\text{ex} = \sqrt{A/K_\text{m}}$, where $K_\text{m}$ is a magnetostatic energy density, $K_\text{m} = \frac{1}{2}\mu_{0}M_\text{s}^{2}$.Material parameters: - uniaxial anisotropy $K_\text{u}$ with $K_\text{u} = 0.1 K_\text{m}$, and with the easy axis directed parallel to a principal axis of the cube (0, 0, 1),- exchange energy constant is $A = \frac{1}{2}\mu_{0}M_\text{s}^{2}l_\text{ex}^{2}$.More details about the standard problem 3 can be found in Ref. 1. Simulation<jupyter_code>import discretisedfield as df
import oommfc as oc
import numpy as np
%matplotlib inline

def m_init_flower(pos):                 
    """Function for initiaising the flower state."""
    x, y, z = pos[0]/1e-9, pos[1]/1e-9, pos[2]/1e-9
    mx = 0
    my = 2*z - 1
    mz = -2*y + 1
    norm_squared = mx**2 + my**2 + mz**2
    if norm_squared <= 0.05:
        return (1, 0, 0)
    else:
        return (mx, my, mz)

def m_init_vortex(pos):
    """Function for initialising the vortex state."""
    x, y, z = pos[0]/1e-9, pos[1]/1e-9, pos[2]/1e-9
    mx = 0
    my = np.sin(np.pi/2 * (x-0.5))
    mz = np.cos(np.pi/2 * (x-0.5))
    return (mx, my, mz)

def minimise_system_energy(L, m_init):
    print("Working on L={} ({})".format(L, m_init.__name__))
    N = 10                      # discretisation in one dimension
    cubesize = 100e-9           # cube edge length (m)
    cellsize = cubesize/N       # discretisation in all three dimensions.
    lex = cubesize/L            # exchange length.
    
    Km = 1e6                    # magnetostatic energy density (J/m**3)
    Ms = np.sqrt(2*Km/oc.mu0)   # magnetisation saturation (A/m)
    A = 0.5 * oc.mu0 * Ms**2 * lex**2  # exchange energy constant
    K = 0.1*Km                  # Uniaxial anisotropy constant
    u = (0, 0, 1)               # Uniaxial anisotropy easy-axis

    p1 = (0, 0, 0)              # Minimum sample coordinate.
    p2 = (cubesize, cubesize, cubesize)  # Maximum sample coordinate.
    cell = (cellsize, cellsize, cellsize)  # Discretisation.
    mesh = oc.Mesh(p1=(0, 0, 0), p2=(cubesize, cubesize, cubesize),
                   cell=(cellsize, cellsize, cellsize))  # Create a mesh object.

    system = oc.System(name="stdprob3")
    system.hamiltonian = oc.Exchange(A) \
                         + oc.UniaxialAnisotropy(K, u) \
                         + oc.Demag()
    system.m = df.Field(mesh, value=m_init, norm=Ms)

    md = oc.MinDriver()         # minimise system energy
    md.drive(system)
    
    return system<jupyter_output><empty_output><jupyter_text>Compute relaxed magnetisation states with one function call**Vortex** state:<jupyter_code>system = minimise_system_energy(8, m_init_vortex)
print("Total energy is {}J".format(system.total_energy()))
system.m.plot_slice('y', 50e-9, xsize=4);<jupyter_output>Working on L=8 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [1.2s]
Total energy is 3.207212348928367e-16J<jupyter_text>**Flower** state:<jupyter_code>system = minimise_system_energy(8, m_init_flower)
print("Total energy is {}J".format(system.total_energy()))
system.m.plot_slice('x', 50e-9, xsize=4);<jupyter_output>Working on L=8 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Total energy is 3.0511659471929853e-16J<jupyter_text>Compute table and plot for energy crossing<jupyter_code>L_array = np.linspace(8, 9, 9)  # values of L for which 
                                # the system is relaxed.
vortex_energies = []
flower_energies = []

for L in L_array:               # iterate through simulation data points
    vortex = minimise_system_energy(L, m_init_vortex)
    flower = minimise_system_energy(L, m_init_flower)
    
    vortex_energies.append(vortex.total_energy())
    flower_energies.append(flower.total_energy())
    
# Plot the results
import matplotlib.pyplot as plt
plt.plot(L_array, vortex_energies, 'o-', label='vortex')
plt.plot(L_array, flower_energies, 'o-', label='flower')
plt.xlabel('L (lex)')
plt.ylabel('E')
plt.xlim([8.0, 9.0])
plt.grid()
plt.legend()<jupyter_output>Working on L=8.0 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.9s]
Working on L=8.0 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.125 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.9s]
Working on L=8.125 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.25 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.25 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.375 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.375 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.5 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.5 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on[...]<jupyter_text>We now know that the energy crossing occurs between $8l_\text{ex}$ and $9l_\text{ex}$, so a root finding algorithm can be used to find the exact crossing.<jupyter_code>from scipy.optimize import bisect

def energy_difference(L):
    vortex = minimise_system_energy(L, m_init_vortex)
    flower = minimise_system_energy(L, m_init_flower)
    
    return vortex.total_energy() - flower.total_energy()

xtol=0.1
cross_section = bisect(energy_difference, 8, 9, xtol=xtol)

print("The transition between vortex and flower states\n" 
      "occurs at {}*lex +-{}".format(cross_section, xtol))<jupyter_output>Working on L=8.0 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.0 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=9.0 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=9.0 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.5 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.5 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8.25 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.8s]
Working on L=8.25 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.9s]
Working on L=8.375 (m_init_vortex)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [1.0s]
Working on L=8.375 (m_init_flower)
2017/4/26 8:28: Calling OOMMF (stdprob3/stdprob3.mif) ... [0.7s]
Working on L=8[...]
{'fraction_non_alphanumeric': 0.1433503659715509, 'fraction_numerical': 0.07195138792984394, 'mean_word_length': 3.4953445065176907, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '145998', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3177, 'n_tokens_neox': 2828, 'n_words': 700, 'path': '0930-Hans/static-standard_problem3.ipynb', 'repo_name': 'OpenDreamKit/tmp-review-meeting-April-2017', 'size': '7241'}