def test_exchange_energy_density(): """ Compare solution with nmag for now. Should derive the analytical solution here as well. Our initial magnetisation looks like this: ^ ~ | / ---> \ | (Hahahaha! :-D) ~ v """ TOL = 1e-7 # Should be lower when comparing with analytical solution MODULE_DIR = os.path.dirname(os.path.abspath(__file__)) # run nmag cmd = "nsim %s --clean" % os.path.join(MODULE_DIR, "run_nmag_Eexch.py") status, output = commands.getstatusoutput(cmd) if status != 0: print output sys.exit("Error %d: Running %s failed." % (status, cmd)) nmag_data = np.loadtxt( os.path.join(MODULE_DIR, "nmag_exchange_energy_density.txt")) # run finmag mesh = df.IntervalMesh(100, 0, 10e-9) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) Ms = 42 m = Field(S3, value=df.Expression( ("cos(x[0]*pi/10e-9)", "sin(x[0]*pi/10e-9)", "0"), degree=1)) exch = Exchange(1.3e-11) Ms_field = Field(df.FunctionSpace(mesh, 'DG', 0), Ms) exch.setup(m, Ms_field) finmag_data = exch.energy_density() rel_err = np.abs(nmag_data - finmag_data) / np.linalg.norm(nmag_data) print("Nmag data = %g" % nmag_data[0]) print("Finmag data = %g" % finmag_data[0]) print "Relative error from nmag data (expect array of 0):" print rel_err print "Max relative error:", np.max(rel_err) assert np.max(rel_err) < TOL, \ "Max relative error is %g, should be zero." % np.max(rel_err) print("Work out average energy density and energy") S1 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=1) # only approximative -- using assemble would be better average_energy_density = np.average(finmag_data) w = df.TestFunction(S1) vol = sum(df.assemble(df.dot(df.Constant([1]), w) * df.dx)) # finmag 'manually' computed, based on node values of energy density: energy1 = average_energy_density * vol # finmag computed by energy class energy2 = exch.compute_energy() # comparison with Nmag energy3 = np.average(nmag_data) * vol print energy1, energy2, energy3 assert abs(energy1 - energy2) < 1e-12 # actual value is 0, but # that must be pure luck. assert abs(energy1 - energy3) < 5e-8 # actual value
nd = np.load(os.path.join(MODULE_DIR, "nmag_hansconf.npy")) # run finmag mesh = df.IntervalMesh(100, 0, 10e-9) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) DG0 = df.FunctionSpace(mesh, "DG", 0) m = Field( S3, df.Expression(("cos(x[0]*pi/10e-9)", "sin(x[0]*pi/10e-9)", "0"), degree=1)) Ms = Field(DG0, 1.0) exchange = Exchange(1.3e-11) exchange.setup(m, Ms) fd = exchange.energy_density() # draw an ASCII table of the findings table_border = "+" + "-" * 8 + "+" + "-" * 64 + "+" table_entries = "| {:<6} | {:<20} {:<20} {:<20} |" table_entries_f = "| {:<6} | {:<20.8f} {:<20.8f} {:<20g} |" print table_border print table_entries.format(" ", "min", "max", "delta") print table_border print table_entries_f.format("finmag", min(fd), max(fd), max(fd) - min(fd)) print table_entries_f.format("nmag", min(nd), max(nd), max(nd) - min(nd)) print table_border # draw a plot of the two exchange energy densities xs = mesh.coordinates().flatten() figure, (upper_axis, lower_axis) = plt.subplots(2, 1, sharex=True)