def __init__(self, Cg, m0, B0, R_E, c_squared): self.Cg = Cg self.m0 = m0 self.B0 = B0 self.R_E = R_E self.c_squared = c_squared self.nv = 40 self.nk = 45 # NB: keep odd to avoid blowups with y = 0! self.nl = 8 self.lmin = 1.1 self.lmax = 7.0 self.logvmin = np.log(1e11) self.logvmax = np.log(1e17) # recall: k{hat}_min => theta_max and vice versa! Y/y = 33 => alpha ~= 4 degr. self.khatmax = (33. * R_E * (B0 / self.lmin)**0.5)**0.2 self.khatmin = -self.khatmax self.vk_mesh = d.RectangleMesh( d.Point(self.logvmin, self.khatmin), d.Point(self.logvmax, self.khatmax), self.nv, self.nk ) self.l_mesh = d.IntervalMesh(self.nl, self.lmin, self.lmax) self.l_boundary = OneDWallExpression(degree=0).configure(0., self.lmax)
def burgers_spacedisc(N=10, nu=None, x0=0.0, xE=1.0, retfemdict=False, condensemats=True): mesh = dolfin.IntervalMesh(N, x0, xE) V = dolfin.FunctionSpace(mesh, 'CG', 1) u = dolfin.TrialFunction(V) v = dolfin.TestFunction(V) # boundaries and conditions ugamma = dolfin.Expression('0', degree=1) def _spaceboundary(x, on_boundary): return on_boundary diribc = dolfin.DirichletBC(V, ugamma, _spaceboundary) mass = assemble(v*u*dx) stif = assemble(nu*inner(nabla_grad(v), nabla_grad(u))*dx) M = dts.mat_dolfin2sparse(mass) A = dts.mat_dolfin2sparse(stif) M, _, bcdict = dts.condense_velmatsbybcs(M, [diribc], return_bcinfo=True) ininds = bcdict['ininds'] A, rhsa = dts.condense_velmatsbybcs(A, [diribc]) def burger_nonl(vvec, t): v0 = expandvfunc(vvec, V=V, ininds=ininds) bnl = assemble(0.5*v*((v0*v0).dx(0))*dx) return bnl.array()[ininds] if retfemdict: return M, A, rhsa, burger_nonl, dict(V=V, diribc=diribc, ininds=ininds) else: return M, A, rhsa, burger_nonl
def test_zhangli(): #mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(100, 1, 1), 50, 1, 1) mesh = df.IntervalMesh(50, 0, 100) sim = Sim(mesh, Ms=8.6e5, unit_length=1e-9, kernel='llg_stt') sim.set_m(init_m) sim.add(UniaxialAnisotropy(K1=520e3, axis=[1, 0, 0])) sim.add(Exchange(A=13e-12)) sim.alpha = 0.01 sim.llg.set_parameters(J_profile=init_J, speedup=50) p0 = sim.m_average sim.run_until(5e-12) p1 = sim.m_average print sim.integrator.stats() print p0, p1 sim.run_until(1e-11) p1 = sim.m_average print sim.integrator.stats() print p0, p1 assert p1[0] < p0[0] assert abs(p0[0]) < 1e-15 assert abs(p1[0]) > 1e-3
def get_domain(self): """ Define the Finite Element domain for the problem """ # Finite Element Mesh in solid self.ice_mesh = dolfin.IntervalMesh(self.n,self.w0,self.wf) self.ice_V = dolfin.FunctionSpace(self.ice_mesh,'CG',1) self.ice_coords = self.ice_V.tabulate_dof_coordinates().copy() self.ice_idx_wall = np.argmin(self.ice_coords) # Finite Element Mesh in solution self.sol_mesh = dolfin.IntervalMesh(self.n,self.Rstar_center,self.Rstar) self.sol_V = dolfin.FunctionSpace(self.sol_mesh,'CG',1) self.sol_mesh.coordinates()[:] = np.log(self.sol_mesh.coordinates()) self.sol_coords = self.sol_V.tabulate_dof_coordinates().copy() self.sol_idx_wall = np.argmax(self.sol_coords) self.flags.append('get_domain')
def test_anisotropy(): mesh = df.IntervalMesh(1, 0, 1) sim = Simulation(mesh, Ms, unit_length=1e-9) sim.set_m((mx, my, mz)) sim.add(UniaxialAnisotropy(K1, axis=[1, 0, 0])) expected = 2 * K1 / (mu0 * Ms) * mx field = sim.effective_field() assert abs(field[0] - expected) / Ms < 1e-15
def test_spatially_varying_anisotropy_axis(tmpdir, debug=False): Ms = 1e6 A = 1.3e-11 K1 = 6e5 lb = bloch_parameter(A, K1) unit_length = 1e-9 nx = 20 Lx = nx * lb / unit_length mesh = df.IntervalMesh(nx, 0, Lx) # anisotropy axis goes from (0, 1, 0) at x=0 to (1, 0, 0) at x=Lx expr_a = df.Expression(("x[0] / sqrt(pow(x[0], 2) + pow(Lx-x[0], 2))", "(Lx-x[0]) / sqrt(pow(x[0], 2) + pow(Lx-x[0], 2))", "0"), Lx=Lx, degree=1) # in theory, a discontinuous Galerkin (constant over the cell) is a good # choice to represent material parameters. In this case though, the # parameter varies linearly, so we use the usual CG. V = df.VectorFunctionSpace(mesh, "CG", 1, dim=3) a = Field(V, expr_a) sim = Simulation(mesh, Ms, unit_length) sim.set_m((1, 1, 0)) sim.add(UniaxialAnisotropy(K1, a)) sim.relax() # probe the easy axis and the magnetisation along the interval points = 100 xs = np.linspace(0, Lx, points) axis_xs = np.zeros((points, 3)) m_xs = np.zeros((points, 3)) for i, x in enumerate(xs): axis_xs[i] = a(x) m_xs[i] = sim.m_field(x) # we want to the magnetisation to follow the easy axis # it does so, except at x=0, what is happening there? diff = np.abs(m_xs - axis_xs) assert diff.max() < 0.02 if debug: old = os.getcwd() os.chdir(tmpdir) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(xs, axis_xs[:, 0], "b+", label="a_x") ax.plot(xs, m_xs[:, 0], "r--", label="m_x") ax.legend(loc="upper left") ax.set_ylim((0, 1.05)) ax.set_xlabel("x (nm)") plt.savefig('spatially_varying_easy_axis.png') plt.close() sim.m_field.save_pvd('spatially_varying_easy_axis.pvd') os.chdir(old)
def build_mesh(self): r""" Build the mesh: (1) check that the input parameters for the mesh are valid (the function performing the test must be defined in the child mesh class) (2) set the mesh transformation. Depending on whether `r\_rm=None` or `r\_rm=float`, the transformation will be the baseline transformation (as defined in the child mesh class) or its updated form declustering mesh points at `r\_rm` (3) create a starting linear mesh, in particular, compute its extrema by using the Newton method (4) obtain a nonlinear mesh by applying the transformation defined at (2) (5) apply additional linear refinement if required (6) check that the obtained mesh points are not closer than the user-set tolerance of :math:`\mathrm{too\_fine}\times\mathrm{DOLFIN\_EPS}`. """ # check input parameters are valid self.check_params() # define transformation - either baseline or with point removal at r_rm if self.r_rm is None: if self.adjust_transition: transform = self.baseline_transform_w_adjusted_xs() else: transform = self.baseline_transform() else: transform = self.transform_with_declustering() self.T, self.Tprime, self.Tprimeprime, self.small_r_Tm1, self.large_r_Tm1 = transform # extrema of starting mesh - find using the Newton method x_min_0 = self.small_r_Tm1(self.r_min) # initial guess F_min = lambda x: self.T(x) - self.r_min self.x_min = sopt.newton(F_min, x_min_0, self.Tprime, tol=self.Ntol) x_max = self.large_r_Tm1(self.r_max) F_max = lambda x: self.T(x) - self.r_max self.x_max = sopt.newton(F_max, x_max, self.Tprime, tol=self.Ntol) # create starting linear mesh from x_min to x_max self.mesh = d.IntervalMesh(self.num_cells, self.x_min, self.x_max) x_mesh = self.mesh.coordinates()[:, 0] # apply transform and get a refined radial mesh T = np.vectorize(self.T) refined_mesh = T(x_mesh) self.mesh.coordinates()[:, 0] = refined_mesh[:] # apply optional linear refinement if required if self.linear_refine: self.apply_linear_refinement() # check that points are not closer than user-set tolerance self.check_mesh()
def set_mesh(self): dx, xmax = self.dx, self.xmax nel = int(xmax/dx) # Number of elements mesh = d.IntervalMesh(nel, 0, xmax) self.mesh = mesh # to output self.cells = {'line': mesh.cells()} xyz = mesh.coordinates() self.xyzio = np.zeros([xyz.shape[0], 3]) self.xyzio[:,0] = xyz.flatten()
def test_llb(do_plot=False): #mesh = df.BoxMesh(0, 0, 0, 2, 2, 2, 1, 1, 1) mesh = df.IntervalMesh(1,0,2) Ms = 8.6e5 sim = LLB(mesh) sim.alpha = 0.5 sim.beta = 0.0 sim.M0 = Ms sim.set_M((Ms,0,0)) sim.set_up_solver(reltol=1e-7, abstol=1e-7) sim.add(Exchange(1.3e-11,chi=1e-7)) H0 = 1e5 sim.add(Zeeman((0, 0, H0))) steps = 100 dt = 1e-12; ts = np.linspace(0, steps * dt, steps+1) precession_coeff = sim.gamma mz_ref = [] mz = [] real_ts=[] for t in ts: print t,sim.Ms sim.run_until(t) real_ts.append(sim.t) mz_ref.append(np.tanh(precession_coeff * sim.alpha * H0 * sim.t)) #mz.append(sim.M[-1]/Ms) # same as m_average for this macrospin problem mz.append(sim.m[-1]) mz=np.array(mz) if do_plot: ts_ns = np.array(real_ts) * 1e9 plt.plot(ts_ns, mz, "b.", label="computed") plt.plot(ts_ns, mz_ref, "r-", label="analytical") plt.xlabel("time (ns)") plt.ylabel("mz") plt.title("integrating a macrospin") plt.legend() plt.savefig(os.path.join(MODULE_DIR, "test_sllg.png")) print("Deviation = {}, total value={}".format( np.max(np.abs(mz - mz_ref)), mz_ref)) assert np.max(np.abs(mz - mz_ref)) < 2e-7
def setup_finmag(): mesh = df.IntervalMesh(xn, x0, x1) coords = np.array(zip(*mesh.coordinates())) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) m = Field(S3) m.set_with_numpy_array_debug(m_gen(coords).flatten()) exchange = Exchange(A) exchange.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms)) H_exc = df.Function(S3) H_exc.vector()[:] = exchange.compute_field() return dict(m=m, H=H_exc, table=start_table())
def setup_module(module=None): x_max = 100e-9 # m simplexes = 50 mesh = dolfin.IntervalMesh(simplexes, 0, x_max) def m_gen(coords): x = coords[0] mx = min(1.0, x / x_max) mz = 0.1 my = np.sqrt(1.0 - (0.99 * mx**2 + mz**2)) return np.array([mx, my, mz]) K1 = 520e3 # J/m^3 Ms = 0.86e6 sim = Sim(mesh, Ms) sim.alpha = 0.2 sim.set_m(m_gen) anis = UniaxialAnisotropy(K1, (0, 0, 1)) sim.add(anis) # Save H_anis and m at t0 for comparison with nmag global H_anis_t0, m_t0 H_anis_t0 = anis.compute_field() m_t0 = sim.m av_f = open(os.path.join(MODULE_DIR, "averages.txt"), "w") tn_f = open(os.path.join(MODULE_DIR, "third_node.txt"), "w") t = 0 t_max = 3e-10 dt = 5e-12 # s while t <= t_max: mx, my, mz = sim.m_average averages.append([t, mx, my, mz]) av_f.write( str(t) + " " + str(mx) + " " + str(my) + " " + str(mz) + "\n") mx, my, mz = h.components(sim.m) m2x, m2y, m2z = mx[2], my[2], mz[2] third_node.append([t, m2x, m2y, m2z]) tn_f.write( str(t) + " " + str(m2x) + " " + str(m2y) + " " + str(m2z) + "\n") t += dt sim.run_until(t) av_f.close() tn_f.close()
def test_spatially_varying_alpha_using_Simulation_class(): """ test that I can change the value of alpha through the property sim.alpha and that I get an df.Function back. """ length = 20 simplices = 10 mesh = df.IntervalMesh(simplices, 0, length) sim = Simulation(mesh, Ms=1, unit_length=1e-9) sim.alpha = 1 expected_alpha = np.ones(simplices + 1) assert np.array_equal(sim.alpha.vector().array(), expected_alpha)
def test_unconstrained_newton_solver(self): L, nelem = 1, 201 mesh = dl.IntervalMesh(nelem, -L, L) Vh = dl.FunctionSpace(mesh, "CG", 2) forcing = dl.Constant(1) dirichlet_bcs = [dl.DirichletBC(Vh, dl.Constant(0.0), on_any_boundary)] bc0 = dl.DirichletBC(Vh, dl.Constant(0.0), on_any_boundary) uh = dl.TrialFunction(Vh) vh = dl.TestFunction(Vh) F = dl.inner((1 + uh**2) * dl.grad(uh), dl.grad(vh)) * dl.dx - forcing * vh * dl.dx u = dl.Function(Vh) F = dl.action(F, u) parameters = { "symmetric": True, "newton_solver": { # "relative_tolerance": 1e-8, "report": True, "linear_solver": "cg", "preconditioner": "petsc_amg" } } dl.solve(F == 0, u, dirichlet_bcs, solver_parameters=parameters) # dl.plot(uh) # plt.show() u_newton = dl.Function(Vh) F = dl.inner((1 + uh**2) * dl.grad(uh), dl.grad(vh)) * dl.dx - forcing * vh * dl.dx F = dl.action(F, u_newton) # Compute Jacobian J = dl.derivative(F, u_newton, uh) unconstrained_newton_solve( F, J, u_newton, dirichlet_bcs=dirichlet_bcs, bc0=bc0, # linear_solver='PETScLU',opts=dict()) linear_solver=None, opts=dict()) error = dl.errornorm(u, u_newton, mesh=mesh) assert error < 1e-15
def test_method_of_computing_the_average_matters(): length = 20e-9 # m simplices = 10 mesh = df.IntervalMesh(simplices, 0, length) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) llg = LLG(S1, S3) llg.set_m(( '(2*x[0]-L)/L', 'sqrt(1 - ((2*x[0]-L)/L)*((2*x[0]-L)/L))', '0'), L=length) average1 = llg.m_average average2 = np.mean(components(llg.m_numpy), axis=1) diff = np.abs(average1 - average2) assert diff.max() > 5e-2
def run_dolfin(): import dolfin as df x_array = np.linspace(-49.5, 49.5, 100) mesh = df.IntervalMesh(100, -50, 50) Delta = np.sqrt(A / K) xi = 2 * A / D Delta_s = Delta * 1e9 V = df.FunctionSpace(mesh, "Lagrange", 1) u = df.TrialFunction(V) v = df.TestFunction(V) u_ = df.Function(V) F = -df.inner(df.nabla_grad(u), df.nabla_grad(v)) * df.dx - \ (0.5 / Delta_s**2) * df.sin(2 * u) * v * df.dx F = df.action(F, u_) J = df.derivative(F, u_, u) # the boundary condition is from equation (8) theta0 = np.arcsin(Delta / xi) ss = 'x[0]<0? %g: %g ' % (-theta0, theta0) u0 = df.Expression(ss) def u0_boundary(x, on_boundary): return on_boundary bc = df.DirichletBC(V, u0, u0_boundary) problem = df.NonlinearVariationalProblem(F, u_, bcs=bc, J=J) solver = df.NonlinearVariationalSolver(problem) solver.solve() u_array = u_.vector().array() mx_df = [] for x in x_array: mx_df.append(u_(x)) return mx_df
def mesh1d(left, right, meshres): mesh = dolfin.IntervalMesh(meshres, left, right) # Construct of the facet markers: boundary = (dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0), {}) #boundary[0].set_all(0) for f in dolfin.facets(mesh): if dolfin.near(f.midpoint()[0], left): boundary[0][f] = 1 # left boundary[1]['inner'] = 1 elif dolfin.near(f.midpoint()[0], right): boundary[0][f] = 2 # right boundary[1]['outer'] = 2 # Definition of measures and normal vector: n = dolfin.FacetNormal(mesh) dx = dolfin.Measure("dx", mesh) ds = dolfin.Measure("ds", subdomain_data=boundary[0]) return (mesh, boundary, n, dx, ds)
def test_spatially_varying_alpha_using_LLG_class(): """ no property magic here - llg.alpha is a df.Function at heart and can be set with any type using llg.set_alpha() """ length = 20 simplices = 10 mesh = df.IntervalMesh(simplices, 0, length) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, 3) llg = LLG(S1, S3) llg.set_alpha(1) expected_alpha = np.ones(simplices + 1) print "Got:\n", llg.alpha.vector().array() print "Expected:\n", expected_alpha assert np.array_equal(llg.alpha.vector().array(), expected_alpha)
def test_non_uniform_external_field(): TOLERANCE = 1e-9 length = 10e-9 vertices = 5 mesh = df.IntervalMesh(vertices, 0, length) sim = Sim(mesh, Ms) sim.set_m((1, 0, 0)) # applied field # (0, -H, 0) for 0 <= x <= a # (0, +H, 0) for a < x <= length H_expr = df.Expression(("0", "H*(x[0]-a)/fabs(x[0]-a)", "0"), a=length / 2, H=Ms / 2, degree=1) sim.add(Zeeman(H_expr)) sim.alpha = 1.0 sim.run_until(1e-9) m = sim.m.reshape((3, -1)).mean(-1) expected_m = np.array([0, 0, 0]) diff = np.abs(m - expected_m) assert np.max(diff) < TOLERANCE
def test_get_interaction_list(): # has bar mini example Demag and Exchange? s = finmag.example.barmini() lst = s.get_interaction_list() assert 'Exchange' in lst assert 'Demag' in lst assert len(lst) == 2 # Let's remove one and ceck again s.remove_interaction('Exchange') assert s.get_interaction_list() == ['Demag'] # test simulation with no interaction s2 = finmag.sim_with(mesh=dolfin.IntervalMesh(10, 0, 1), m_init=(1, 0, 0), Ms=1, demag_solver=None, unit_length=1e-8) assert s2.get_interaction_list() == []
def setup_domain_wall_cobalt(node_count=NODE_COUNT, A=A_Co, Ms=Ms_Co, K1=K1_Co, length=LENGTH, do_precession=True): mesh = df.IntervalMesh(node_count - 1, 0, length) S1 = df.FunctionSpace(mesh, "Lagrange", 1) S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3) llg = LLG(S1, S3) llg.set_m( np.array([initial_m(xi, node_count) for xi in xrange(node_count)]).T.reshape((-1, ))) exchange = Exchange(A) llg.effective_field.add(exchange) anis = UniaxialAnisotropy(K1, (0, 0, 1)) llg.effective_field.add(anis) llg.pins = [0, node_count - 1] return llg
def test_anisotropy_energy_density(): """ Written in sperical coordinates, the equation for the anisotropy energy density reads E/V = K*sin^2(theta), where theta is the angle between the magnetisation and the easy axis. With a magnetisation pointing 45 degrees between the x- and z-axis, and using the z-axis as the easy axis, theta becomes pi/4. sin^2(pi/4) evaluates to 1/2, and with K set to 1 in this simple test case, we expect the energy density to be 1/2 at every node. """ # 5 simplices between 0 and 1 nm. mesh = df.IntervalMesh(5, 0, 1e-9) V = df.VectorFunctionSpace(mesh, "CG", 1, dim=3) # Initial magnetisation 45 degress between x- and z-axis. m_vec = df.Constant((1 / np.sqrt(2), 0, 1 / np.sqrt(2))) m = Field(V, value=m_vec) # Easy axis in z-direction. a = df.Constant((0, 0, 1)) # These are 1 just to simplify the analytical solution. K = 1 Ms = 1 anis = UniaxialAnisotropy(K, a) anis.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms)) density = anis.energy_density() deviation = np.abs(density - 0.5) print "Anisotropy energy density (expect array of 0.5):" print density print "Max deviation: %g" % np.max(deviation) assert np.all(deviation < TOL), \ "Max deviation %g, should be zero." % np.max(deviation)
def one_dimensional_problem(): x_min = 0 x_max = 100e-9 x_n = 100000 dolfin_mesh = df.IntervalMesh(x_n, x_min, x_max) oommf_mesh = mesh.Mesh((20, 1, 1), size=(x_max, 1e-12, 1e-12)) def m_gen(rs): xs = rs[0] return np.array( [xs / x_max, np.sqrt(1 - (xs / x_max)**2), np.zeros(len(xs))]) return compare_anisotropy(m_gen, Ms, K1, (1, 1, 1), dolfin_mesh, oommf_mesh, dims=1, name="1D")
def __init__(self, t_end, start_cells, perc, do_step=None, do_step_adj=None, get_dwr_est=None, j=None): ## time discretization self.mesh = dol.IntervalMesh(int(start_cells), 0, int(t_end)) ## percentage of cells to refine in a single refinement step self.perc = perc ## end time self.t_end = t_end self.do_step = do_step self.do_step_adj = do_step_adj ## dwr estimate function self.get_dwr_est = get_dwr_est self.j = j ## time discretization self.times = []
def instantiate(self, N, dtype, regular_mesh=None): """ Return a pair (A, None), where A is a matrix representing the action on a vector v given by the right-hand side of the linearised LLG equation (without damping): A*v = dv/dt = -gamma * m_0 x H_exchange(v) """ if not iseven(N): raise ValueError("N must be even. Got: {}".format(N)) # XXX TODO: Actually, we shouldn't store these values in 'self' # because we can always re-instantiate the problem, # right? self.N = N self.dtype = dtype if regular_mesh == None: regular_mesh = self.regular_mesh self.K = N // 2 if regular_mesh: mesh = df.IntervalMesh(self.K - 1, self.xmin, self.xmax) else: mesh = irregular_interval_mesh(self.xmin, self.xmax, self.K) #raise NotImplementedError() V = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3) v = Field(V) self.exch = Exchange(A=self.A_ex) Ms_field = Field(df.FunctionSpace(mesh, 'DG', 0), self.Ms) self.exch.setup(v, Ms_field, unit_length=self.unit_length) C_2Kx2K = LinearOperator( shape=(N, N), matvec=self.compute_action_rhs_linearised_LLG_2K, dtype=dtype) C_2Kx2K_dense = as_dense_array(C_2Kx2K) return C_2Kx2K_dense, None
def __init__(self, odcoo, gamma=1e-3, alphau=1e-6, ystar=None): if ystar is None: self.ystarx = dolfin.Expression('-0.1*sin(5*3.14*t)', t=0) self.ystary = dolfin.Expression('0.1*sin(5*3.14*t)', t=0) # self.ystarx = dolfin.Expression('-0.0', t=0) # self.ystary = dolfin.Expression('0.0', t=0) # if t, then add t=0 to both comps !!1!!11 else: self.ystarx = ystar[0] self.ystary = ystar[1] self.NU, self.NY = 4, 4 self.R = None # regularization parameter self.alphau = alphau # weighting of the penalization of the terminal value self.gamma = gamma self.V = None self.W = None self.ymesh = dolfin.IntervalMesh(self.NY - 1, odcoo['ymin'], odcoo['ymax']) self.Y = dolfin.FunctionSpace(self.ymesh, 'CG', 1)
def test_1d(): print "1D problem..." for x_n in [1e1, 1e2, 1e3, 1e4, 1e5, 1e6]: dolfin_mesh = df.IntervalMesh(int(x_n), 0, x_max) oommf_mesh = mesh.Mesh((int(x_n), 1, 1), size=(x_max, 1e-12, 1e-12)) res = compare_anisotropy(m_gen, 1.0, K1, (1, 1, 1), dolfin_mesh, oommf_mesh, dims=1, name="1D") vertices[0].append(dolfin_mesh.num_vertices()) mean_rdiffs[0].append(np.mean(res["rel_diff"])) max_rdiffs[0].append(np.max(res["rel_diff"])) def linear(x, a, b): return a * x + b xs = np.log(vertices[0]) ys = np.log(mean_rdiffs[0]) popt, pcov = curve_fit(linear, xs, ys) assert popt[0] < -1.0
def simple_mesh(Ld, N, ext_bnd_id=1): """ Returns a mesh for a given list, Ld, containing the size of domain in each spatial direction, and the corresponding number of cell divisions N. """ d = len(N) mesh_types = [df.RectangleMesh, df.BoxMesh] if d == 1: mesh = df.IntervalMesh(N[0], 0.0, Ld[0]) else: mesh = mesh_types[d - 2](df.Point(*np.zeros(len(Ld))), df.Point(*Ld), *N) facet_func = df.FacetFunction('size_t', mesh) facet_func.set_all(0) class ExtBnd(df.SubDomain): def inside(self, x, on_boundary): return on_boundary bnd = ExtBnd() bnd.mark(facet_func, ext_bnd_id) return mesh, facet_func
def __init__(self, tfml_file, system_name='magma', p_name='Pressure', f_name='Porosity', c_name='c', n_name='n', m_name='m', d_name='d', N_name='N', h_squared_name='h_squared', x0_name='x0'): """read the tfml_file and use libspud to populate the internal parameters c: wavespeed n: permeability exponent m: bulk viscosity exponent d: wave dimension N: number of collocation points x0: coordinate wave peak h_squared: the size of the system in compaction lengths squared (h/delta)**2 """ # initialize libspud and extract parameters libspud.clear_options() libspud.load_options(tfml_file) # get model dimension self.dim = libspud.get_option("/geometry/dimension") self.system_name = system_name # get solitary wave parameters path = "/system::" + system_name + "/coefficient::" scalar_value = "/type::Constant/rank::Scalar/value::WholeMesh/constant" vector_value = "/type::Constant/rank::Vector/value::WholeMesh/constant::dim" c = libspud.get_option(path + c_name + scalar_value) n = int(libspud.get_option(path + n_name + scalar_value)) m = int(libspud.get_option(path + m_name + scalar_value)) d = float(libspud.get_option(path + d_name + scalar_value)) N = int(libspud.get_option(path + N_name + scalar_value)) self.h = np.sqrt( libspud.get_option(path + h_squared_name + scalar_value)) self.x0 = np.array(libspud.get_option(path + x0_name + vector_value)) self.swave = SolitaryWave(c, n, m, d, N) self.rmax = self.swave.r[-1] self.tfml_file = tfml_file # check that d <= dim assert (d <= self.dim) # sort out appropriate index for calculating distance r if d == 1: self.index = [self.dim - 1] else: self.index = range(0, int(d)) # check that the origin point is the correct dimension assert (len(self.x0) == self.dim) #read in information for constructing Function space and dolfin objects # get the mesh parameters and reconstruct the mesh meshtype = libspud.get_option("/geometry/mesh/source[0]/name") if meshtype == 'UnitSquare': number_cells = libspud.get_option( "/geometry/mesh[0]/source[0]/number_cells") diagonal = libspud.get_option( "/geometry/mesh[0]/source[0]/diagonal") mesh = df.UnitSquareMesh(number_cells[0], number_cells[1], diagonal) elif meshtype == 'Rectangle': x0 = libspud.get_option( "/geometry/mesh::Mesh/source::Rectangle/lower_left") x1 = libspud.get_option( "/geometry/mesh::Mesh/source::Rectangle/upper_right") number_cells = libspud.get_option( "/geometry/mesh::Mesh/source::Rectangle/number_cells") diagonal = libspud.get_option( "/geometry/mesh[0]/source[0]/diagonal") mesh = df.RectangleMesh(x0[0], x0[1], x1[0], x1[1], number_cells[0], number_cells[1], diagonal) elif meshtype == 'UnitCube': number_cells = libspud.get_option( "/geometry/mesh[0]/source[0]/number_cells") mesh = df.UnitCubeMesh(number_cells[0], number_cells[1], number_cells[2]) elif meshtype == 'Box': x0 = libspud.get_option( "/geometry/mesh::Mesh/source::Box/lower_back_left") x1 = libspud.get_option( "/geometry/mesh::Mesh/source::Box/upper_front_right") number_cells = libspud.get_option( "/geometry/mesh::Mesh/source::Box/number_cells") mesh = df.BoxMesh(x0[0], x0[1], x0[2], x1[0], x1[1], x1[2], number_cells[0], number_cells[1], number_cells[2]) elif meshtype == 'UnitInterval': number_cells = libspud.get_option( "/geometry/mesh::Mesh/source::UnitInterval/number_cells") mesh = df.UnitIntervalMesh(number_cells) elif meshtype == 'Interval': number_cells = libspud.get_option( "/geometry/mesh::Mesh/source::Interval/number_cells") left = libspud.get_option( "/geometry/mesh::Mesh/source::Interval/left") right = libspud.get_option( "/geometry/mesh::Mesh/source::Interval/right") mesh = df.IntervalMesh(number_cells, left, right) elif meshtype == 'File': mesh_filename = libspud.get_option( "/geometry/mesh::Mesh/source::File/file") print "tfml_file = ", self.tfml_file, "mesh_filename=", mesh_filename mesh = df.Mesh(mesh_filename) else: df.error("Error: unknown mesh type " + meshtype) #set the functionspace for n-d solitary waves path = "/system::" + system_name + "/field::" p_family = libspud.get_option(path + p_name + "/type/rank/element/family") p_degree = libspud.get_option(path + p_name + "/type/rank/element/degree") f_family = libspud.get_option(path + f_name + "/type/rank/element/family") f_degree = libspud.get_option(path + f_name + "/type/rank/element/degree") pe = df.FiniteElement(p_family, mesh.ufl_cell(), p_degree) ve = df.FiniteElement(f_family, mesh.ufl_cell(), f_degree) e = pe * ve self.functionspace = df.FunctionSpace(mesh, e) #work out the order of the fields for i in xrange( libspud.option_count("/system::" + system_name + "/field")): name = libspud.get_option("/system::" + system_name + "/field[" + ` i ` + "]/name") if name == f_name: self.f_index = i if name == p_name: self.p_index = i
import numpy as np import dolfin as df from finmag import Simulation as Sim from finmag.energies import Exchange from finmag.util.helpers import vectors, angle TOLERANCE = 8e-7 # define the mesh length = 20e-9 # m simplexes = 10 mesh = df.IntervalMesh(simplexes, 0, length) Ms = 8.6e5 A = 1.3e-11 # initial configuration of the magnetisation left_right = '2*x[0]/L - 1' up_down = 'sqrt(1 - (2*x[0]/L - 1)*(2*x[0]/L - 1))' possible_orientations = [ (left_right, up_down, '0'), # (left_right, '0', up_down), (up_down, '0', left_right)] # , (up_down, left_right, '0'), #('0', left_right, up_down)] , ('0', up_down, left_right)] def angles_after_a_nanosecond(initial_M, pins=[]): sim = Sim(mesh, Ms) sim.set_m(initial_M, L=length) sim.add(Exchange(A)) sim.pins = pins sim.run_until(1e-9)
) # or x[0] > 1.0 - dl.DOLFIN_EPS def pde_varf(u, m, p): return dl.inner(dl.nabla_grad(u), dl.nabla_grad(p)) * dl.dx + u * p * dl.dx - m * p * dl.dx # return u * p * dl.dx - m * p * dl.dx # create mesh dl.set_log_active(False) sep = "\n" + "#" * 80 + "\n" nx = 256 mesh = dl.IntervalMesh(dl.mpi_comm_self(), nx, 0., 1.) # define function space Vh2 = dl.FunctionSpace(mesh, 'Lagrange', 1) Vh1 = dl.FunctionSpace(mesh, 'Lagrange', 1) Vh = [Vh2, Vh1, Vh2] ndofs = [Vh[STATE].dim(), Vh[PARAMETER].dim(), Vh[ADJOINT].dim()] if rank == 0: print(sep, "Set up the mesh and finite element spaces", sep) print( "Number of dofs: STATE={0}, PARAMETER={1}, ADJOINT={2}".format(*ndofs)) # define boundary conditions and PDE u_bdr = dl.Expression("1-x[0]", degree=1) u_bdr0 = dl.Constant(0.0)