def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = 0.5 * as_matrix( [[cos(self.gamma[0]), sin(self.gamma[0])], [- sin(self.gamma[0]), cos(self.gamma[0])]]) \ * as_matrix([[20, 1], [1, 0.1]]) \ * as_matrix( [[cos(self.gamma[0]), - sin(self.gamma[0])], [sin(self.gamma[0]), cos(self.gamma[0])]]) self.b = as_vector([Constant(0.0), Constant(1.0)]) self.c = Constant(-10.0) self.u_ = (2*x-1.) \ * (exp(1 - abs(2*x-1.)) - 1) \ * (y + (1 - exp(y/self.delta))/(exp(1/self.delta)-1)) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) \ + inner(self.b, grad(self.u_)) \ + self.c * self.u_ # Set boundary conditions self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # r = .1*sqrt((x-np.pi)**2 + (y-np.pi)**2) # self.u_ = pow(r,1.5) * sin(x) * sin(y) # Set up explicit solution self.u_ = sin(x) * sin(y) # Init coefficient matrix self.a1 = as_matrix([[2, .5], [ 0.5, 1.5 ]]) + conditional(x * y > 0, 1., -1.) * as_matrix([[1., .5], [.5, .5]]) self.a2 = as_matrix([[1.5, .5], [ 0.5, 2. ]]) + conditional(x * y > 0, 1., -1.) * as_matrix([[.5, .5], [.5, 1.]]) self.a = self.gamma[0] * self.a1 + (1. - self.gamma[0]) * self.a2 # Init right-hand side self.f1 = inner(self.a1, grad(grad(self.u_))) self.f2 = inner(self.a2, grad(grad(self.u_))) self.fcond = conditional(x * y > 0, 0., 1.) # self.f = self.fcond * self.f1 + (1.-self.fcond) * self.f2 self.f = self.gamma[0] * self.f1 + (1. - self.gamma[0]) * self.f2 # conditional(x*x*x-y>0.0,2.0,1.0)]]) # self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = Constant(0.0)
def eval(self, values, x): # Discretize control set n_alpha = 200 alpha_space = np.linspace(self.amin, self.amax, n_alpha + 1) alpha_space = alpha_space[:-1] vxx = np.ndarray((1, )) vxy = np.ndarray((1, )) vyx = np.ndarray((1, )) vyy = np.ndarray((1, )) self.dxx.eval(vxx, x) self.dxy.eval(vxy, x) self.dyx.eval(vyx, x) self.dyy.eval(vyy, x) maxres = -1e10 # print(x) for alpha in alpha_space: R = np.array([[cos(alpha), -sin(alpha)], [sin(alpha), cos(alpha)]]) A = 0.5 * R.T @ np.array([[20, 1], [1, 0.1]]) @ R res = A[0, 0] * vxx \ + A[0, 1] * vxy \ + A[1, 0] * vyx \ + A[1, 1] * vyy if res > maxres: maxres = res values[:] = alpha
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i)/(self.k0*Z0) H_i = curl(self.E_r)/(self.k0*Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r*dolfin.cos(phase) - J_i*dolfin.sin(phase) N_i = J_r*dolfin.sin(phase) + J_i*dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict( r_theta=dot(theta_hat, N_r)*ds, r_phi=dot(phi_hat, N_r)*ds, i_theta=dot(theta_hat, N_i)*ds, i_phi=dot(phi_hat, N_i)*ds) return self.N_form
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1., 0.], [0., 1.]]) self.u_ = sin(pi * x) * sin(pi * y) self.f = inner(self.a, grad(grad(self.u_))) self.g = Constant(0.0)
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = 0.5 * as_matrix( [[cos(self.gamma[0]), sin(self.gamma[0])], [- sin(self.gamma[0]), cos(self.gamma[0])]]) \ * as_matrix([[1, sin(self.gamma[1])], [0, cos(self.gamma[1])]]) \ * as_matrix([[1, 0], [sin(self.gamma[1]), cos(self.gamma[1])]]) \ * as_matrix( [[cos(self.gamma[0]), - sin(self.gamma[0])], [sin(self.gamma[0]), cos(self.gamma[0])]]) self.b = as_vector([Constant(0.0), Constant(0.0)]) self.c = -pi**2 self.u_ = exp(x * y) * sin(pi * x) * sin(pi * y) # Init right-hand side self.f = - sqrt(3) * (sin(self.gamma[1])/pi)**2 \ + 111111 # TODO work here # Set boundary conditions self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1.0, self.kappa], [self.kappa, 1.0]]) # Init right-hand side self.f = (1 + x**2) * sin(pi * x) * sin(2 * pi * y) # Set boundary conditions to exact solution self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[Constant(1.), Constant(self.kappa)], [Constant(self.kappa), Constant(1.)]]) self.u_ = sin(2 * pi * x) * sin(2 * pi * y) self.f = inner(self.a, grad(grad(self.u_))) self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) z = pow(sqrt(pow(x, 2) + pow(y, 2)), .5) # Init coefficient matrix self.a = as_matrix([[z + 1., -z], [-z, 5 * z + 1.]]) self.u_ = sin(2 * pi * x) * sin(2 * pi * y) * exp(x * cos(y)) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def __init__(self, V, **kwargs): # Call parent ParametrizedProblem.__init__( self, os.path.join("test_eim_approximation_14_tempdir", expression_type, basis_generation, "mock_problem")) # Minimal subset of a ParametrizedDifferentialProblem self.V = V self._solution = Function(V) self.components = ["u", "s", "p"] # Parametrized function to be interpolated x = SpatialCoordinate(V.mesh()) mu = SymbolicParameters(self, V, (1., )) self.f00 = (1 - x[0]) * cos(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] * (1 + x[0])) self.f01 = (1 - x[0]) * sin(3 * pi * mu[0] * (1 + x[0])) * exp(-mu[0] * (1 + x[0])) # Inner product f = TrialFunction(self.V) g = TestFunction(self.V) self.inner_product = assemble(inner(f, g) * dx) # Collapsed vector and space self.V0 = V.sub(0).collapse() self.V00 = V.sub(0).sub(0).collapse() self.V1 = V.sub(1).collapse()
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[ 2.0, sin(pi * (20 * x * y + .5)) * conditional(x * y > 0, 1, -1) ], [sin(pi * (20 * x * y + .5)) * conditional(x * y > 0, 1, -1), 2.0]]) self.u_ = x * y * sin(2 * pi * x) * \ sin(3 * pi * y) / (x ** 2 + y ** 2 + 1) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix( [[1., 0.], [0., 2. + atan(self.K * (pow(x, 2) + pow(y, 2) - 1.0))]]) # Init exact solution self.u_ = sin(pi * x) * sin(pi * y) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) mu = 1 # Init coefficient matrix self.a = as_matrix([[1., Constant(0.)], [Constant(0.), 1.]]) self.u_ = exp(-mu * (self.T[1] - self.t)) * sin(2 * pi * x) * sin(1 * pi * y) self.u_T = ufl.replace(self.u_, {self.t: self.T[1]}) # Init right-hand side self.f = mu * self.u_ + inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = Constant(0.0)
def updateCoefficients(self): x = SpatialCoordinate(self.mesh)[0] # Init coefficient matrix self.a = as_matrix([[Constant(1.)]]) self.b = as_vector([Constant(0.2)]) self.c = Constant(0.1) self.u_ = 0.5 * (self.t**2 + 1) * sin(2 * x * pi) self.u_T = ufl.replace(self.u_, {self.t: self.T[1]}) # Init right-hand side self.f = self.t * sin(2*pi*x) \ + inner(self.a, grad(grad(self.u_))) \ + inner(self.b, grad(self.u_)) \ + self.c * self.u_ self.g = Constant(0.0)
def get_residual_form(u, v, rho_e, phi_angle, k, alpha, method='RAMP', Th=df.Constant(1.)): if method == 'SIMP': C = rho_e**3 else: C = rho_e / (1 + 8. * (1. - rho_e)) E = k # C is the design variable, its values is from 0 to 1 nu = 0.49 # Poisson's ratio lambda_ = E * nu / (1. + nu) / (1 - 2 * nu) mu = E / 2 / (1 + nu) #lame's parameters # Th = df.Constant(5e1) # Th = df.Constant(1.) # Th = df.Constant(5e0) w_ij = 0.5 * (df.grad(u) + df.grad(u).T) v_ij = 0.5 * (df.grad(v) + df.grad(v).T) S = df.as_matrix([[-2., 0., 0.], [0., 1., 0.], [0., 0., 1.]]) L = df.as_matrix([[df.cos(phi_angle), df.sin(phi_angle), 0.], [-df.sin(phi_angle), df.cos(phi_angle), 0.], [0., 0., 1.]]) alpha_e = alpha * C eps = w_ij - alpha_e * Th * L.T * S * L d = len(u) sigm = lambda_ * df.div(u) * df.Identity(d) + 2 * mu * eps a = df.inner(sigm, v_ij) * df.dx return a
def get_L_form(self): try: return self.L_form except AttributeError: pass # Set up equivalent magnetic current forms M_r = -cross(self.n, self.E_r) M_i = -cross(self.n, self.E_i) #------------------------------ # Set up form for far field potential L theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase L_r = M_r * dolfin.cos(phase) - M_i * dolfin.sin(phase) L_i = M_r * dolfin.sin(phase) + M_i * dolfin.cos(phase) self.L_form = dict(r_theta=dot(theta_hat, L_r) * ds, r_phi=dot(phi_hat, L_r) * ds, i_theta=dot(theta_hat, L_i) * ds, i_phi=dot(phi_hat, L_i) * ds) return self.L_form
def get_L_form(self): try: return self.L_form except AttributeError: pass # Set up equivalent magnetic current forms M_r = -cross(self.n, self.E_r) M_i = -cross(self.n, self.E_i) #------------------------------ # Set up form for far field potential L theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase L_r = M_r*dolfin.cos(phase) - M_i*dolfin.sin(phase) L_i = M_r*dolfin.sin(phase) + M_i*dolfin.cos(phase) self.L_form = dict( r_theta=dot(theta_hat, L_r)*ds, r_phi=dot(phi_hat, L_r)*ds, i_theta=dot(theta_hat, L_i)*ds, i_phi=dot(phi_hat, L_i)*ds) return self.L_form
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = self.gamma[0] * as_matrix([[1.0, 0.0], [0.0, 1.0]]) self.b = as_vector([Constant(0.0), Constant(0.0)]) self.c = Constant(0.0) # Init right-hand side # self.f_t = 529 * (sin(xxx) + 0.5 * sin(2 * xxx) + 4./10 * sin(8 * xxx))**2 # self.f_t = (sin(pi**2*(x-0.63)*(y-0.26)/0.07))**2 # self.f_t = Constant(1.) # self.u_ = sin(pi*x) * sin(pi * y) # self.f = -self.alpha1 * 2 * pi**2 * sin(pi*x) * sin(pi*y) self.u_ = sin(2 * pi * x) * sin(2 * pi * y) self.f = -conditional( (x - 0.5) * (y - 0.5) > 0, self.alpha1, self.alpha0) * 8 * pi**2 * self.u_ # Set boundary conditions self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix( [[pow(abs(sin(4 * pi * (x - 0.5))), 1.0 / 5), cos(2 * pi * x * y)], [ cos(2 * pi * x * y), pow(abs(sin(4 * pi * (y - 0.5))), 1.0 / 5) + 1. ]]) # Init exact solution self.u_ = x * y * sin(2 * pi * x) * sin( 3 * pi * y) / (pow(x, 2) + pow(y, 2) + 1) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = self.gamma[0] * as_matrix([[1.0, 0.0], [0.0, 1.0]]) self.b = as_vector([self.gamma[1], self.gamma[2]]) # Init right-hand side # self.f_t = 529 * (sin(xxx) # + 0.5 * sin(2 * xxx) + 4./10 * sin(8 * xxx))**2 # self.f_t = (sin(pi**2*(x-0.63)*(y-0.26)/0.07))**2 # self.f_t = Constant(1.) self.f = -10 * (sin(pi**2 * (x - 0.63) * (y - 0.26) / 0.07) + 0.5 * sin(2 * pi**2 * (x - 0.63) * (y - 0.26) / 0.07) + 4. / 10 * sin(8 * pi**2 * (x - 0.63) * (y - 0.26) / 0.07))**2 # Set boundary conditions self.g = Constant(0.0) self.u_T = Constant(0.0)
def initControl(self): self.controlSpace = [ FunctionSpace(self.mesh, "DG", 1), FunctionSpace(self.mesh, "DG", 1) ] u_x = Dx(self.u, 0) u_y = Dx(self.u, 1) # phi = atan(u_y/u_x) <==> sin(phi) / cos(phi) = u_y / u_x self.gamma = [] phi = ufl.atan_2(u_y, u_x) self.gamma.append(1. / self.alpha * (cos(phi) * u_x + sin(phi) * u_y)) self.gamma.append(phi)
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i) / (self.k0 * Z0) H_i = curl(self.E_r) / (self.k0 * Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r * dolfin.cos(phase) - J_i * dolfin.sin(phase) N_i = J_r * dolfin.sin(phase) + J_i * dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict(r_theta=dot(theta_hat, N_r) * ds, r_phi=dot(phi_hat, N_r) * ds, i_theta=dot(theta_hat, N_i) * ds, i_phi=dot(phi_hat, N_i) * ds) return self.N_form
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1., 0], [0, self.eps]]) self.b = as_vector([0.0, -10 * (y - 0.5) * x]) self.c = Constant(0.0) # self.u_T = Constant(0) self.u_ = 0.5 * (self.t**2 + 1) * sin(2 * x * pi) * sin(2 * y * pi) self.u_T = ufl.replace(self.u_, {self.t: self.T[1]}) # Init right-hand side self.f = +self.t * sin(2*pi*x) * sin(2*pi*y) \ + inner(self.a[0][0], Dx(Dx(self.u_, 0), 0)) \ + inner(self.b, grad(self.u_)) \ + self.c * self.u_ # self.f = +self.t * sin(2*pi*x) * sin(2*pi*y) \ # + inner(self.a, grad(grad(self.u_))) \ # + inner(self.b, grad(self.u_)) \ # + self.c * self.u_ self.g = Constant(0.0)
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1., 0.], [0., 2.0 + sin(1.0 / (abs(x) + abs(y)))]]) # Init exact solution self.u_ = pow(2 - pow(x, 2) - pow(y, 2), 0.5) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): x, y = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1., Constant(0.)], [Constant(0.), 1.]]) # Set up explicit solution r = sqrt(x**2 + y**2) phi = atan_2(x, y) self.u_ = r**self.alpha * sin(2. * phi) * (1 - x) * (1 - y) # Init right-hand side self.f = inner(self.a, grad(grad(self.u_))) # Set boundary conditions to exact solution self.g = self.u_
def updateCoefficients(self): # Init coefficient matrix x, y = SpatialCoordinate(self.mesh) self.a = as_matrix([[1.0, 0.0], [0.0, 1.0]]) # self.a = as_matrix([[1.0 , 0.0], [0.0, 1.0]]) self.b = -self.gamma[0] * \ as_vector([cos(self.gamma[1]), sin(self.gamma[1])]) # self.u_ = x*y*(1-exp(1-abs(x))) * (1-exp(1-abs(y))) # Init right-hand side self.f = -1 \ - 0.5 * self.alpha * sqrt(pow(self.gamma[0], 2)) # Set boundary conditions self.g = Constant(0.0)
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 deformation_vector(): n1 = (1 + x1[0] * sin(2 * pi * x1[1])) * VolumeNormal(multimesh.part(1)) S_sm = VectorFunctionSpace(multimesh.part(1), "CG", 1) # Note removing 0 dirichlet at dI introduces problems with the change in # the cut cell and overlap cell part. We do not have any way of describing # this movement bcs = [ DirichletBC(S_sm, n1, mfs[1], 2), DirichletBC(S_sm, Constant((0, 0)), mfs[1], 1) ] u, v = TrialFunction(S_sm), TestFunction(S_sm) a = inner(grad(u), grad(v)) * dx l = inner(Constant((0., 0.)), v) * dx n = Function(S_sm) solve(a == l, n, bcs=bcs) S = MultiMeshVectorFunctionSpace(multimesh, "CG", 1) s = MultiMeshFunction(S) s.assign_part(1, n) return s
def __init__(self, mesh, *, domains = None, facets = None, coefficients = None): super().__init__(mesh, domains = domains, facets = facets) coeffs = self.coefficient_functions(coefficients) cos = dolfin.cos(coeffs['angle']) sin = dolfin.sin(coeffs['angle']) ax_0, ax_1, ax_2 = coeffs['axis_0'], coeffs['axis_1'], coeffs['axis_2'] E_0, E_1, E_2 = coeffs['E_0'], coeffs['E_1'], coeffs['E_2'] nu_01, nu_02, nu_12 = coeffs['nu_01'], coeffs['nu_02'], coeffs['nu_12'] self.G_01, self.G_02, self.G_12 = coeffs['G_01'], coeffs['G_02'], coeffs['G_12'] self.RR = dolfin.as_matrix([ [cos + ax_0*ax_0*(1 - cos), ax_0*ax_1*(1 - cos) - ax_2*sin, ax_0*ax_2*(1 - cos) + ax_1*sin], [ax_0*ax_1*(1 - cos) + ax_2*sin, cos + ax_1*ax_1*(1 - cos), ax_1*ax_2*(1 - cos) - ax_0*sin], [ax_0*ax_2*(1 - cos) - ax_1*sin, ax_1*ax_2*(1 - cos) + ax_0*sin, cos + ax_2*ax_2*(1 - cos)] ]) nu_10 = nu_01*E_1/E_0; nu_20 = nu_02*E_2/E_0; nu_21 = nu_12*E_2/E_1 kk = 1 - nu_01*nu_10 - nu_12*nu_21 - nu_02*nu_20 - 2*nu_01*nu_12*nu_20 self.DD = dolfin.as_matrix([ [E_0*(1 - nu_12*nu_21)/kk, E_0*(nu_12*nu_20 + nu_10)/kk, E_0*(nu_21*nu_10 + nu_20)/kk], [E_1*(nu_02*nu_21 + nu_01)/kk, E_1*(1 - nu_02*nu_20)/kk, E_1*(nu_20*nu_01 + nu_21)/kk], [E_2*(nu_01*nu_12 + nu_02)/kk, E_2*(nu_10*nu_02 + nu_12)/kk, E_2*(1 - nu_01*nu_10)/kk] ])
def updateCoefficients(self): x, y, z = SpatialCoordinate(self.mesh) # Init coefficient matrix self.a = as_matrix([[1, 0, 0], [0, 2, 0], [0, 0, 1]]) self.b = as_vector([0.2, -0.1, 0.1]) self.c = Constant(0.1) self.u_ = 0.5 * \ (self.t**2+1) * sin(2*x*pi) * sin(2*y*pi) * sin(2*z*pi) # self.u_T = ufl.replace(self.u_, {self.t: self.T[1]}) # Init right-hand side self.f = +self.t * sin(2*pi*x) * sin(2*pi*y)*sin(2*pi*z) \ + inner(self.a, grad(grad(self.u_))) \ + inner(self.b, grad(self.u_)) \ + self.c * self.u_ self.g = Constant(0.0)
def eval(self, values, x): y_0 = -H + a0 * (exp(-((x[0]-L/2.)**2 + (x[1]-L/2.)**2) / sigma**2)) values[0] = sin(theta)/cos(theta) * (x[0] + sin(theta)*y_0) \ + cos(theta)*y_0
def bc_eval(self, t): return (sin(t), sin(t))
def test_prb88_184422(): mu0 = 4 * np.pi * 1e-7 Ms = 8.6e5 A = 16e-12 D = 3.6e-3 K = 510e3 mesh = CuboidMesh(nx=100, dx=1, unit_length=1e-9) sim = Sim(mesh) sim.driver.set_tols(rtol=1e-10, atol=1e-14) sim.driver.alpha = 0.5 sim.driver.gamma = 2.211e5 sim.Ms = Ms sim.do_precession = False sim.set_m((0, 0, 1)) sim.add(UniformExchange(A)) sim.add(DMI(-D, type='interfacial')) sim.add(UniaxialAnisotropy(K, axis=(0, 0, 1))) sim.relax(dt=1e-13, stopping_dmdt=0.01, max_steps=5000, save_m_steps=None, save_vtk_steps=50) m = sim.spin mx, my, mz = np.split(m, 3) x_array = np.linspace(-49.5, 49.5, 100) #plt.plot(x_array, mx) #plt.plot(x_array, my) #plt.plot(x_array, mz) 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)) #plt.plot(x_array, mx_df) assert abs(np.max(mx - mx_df)) < 0.05
def linear_interpolation_two(self, image0, image1, n): """ Define a linear interpolation between two states of the energy band (m0, m1) to get an initial state. The interpolation is done in the magnetic moments that constitute the magnetic system. """ # Get the spherical coordinates dolfin functions # for the m0 and m1 magnetisation vector fields self.sim.set_m(self.initial_images[image0]) theta0, phi0 = self.sim._m_field.get_spherical() self.sim.set_m(self.initial_images[image1]) theta1, phi1 = self.sim._m_field.get_spherical() # To not depend on numpy arrays, we will assemble every # interpolation into dolfin functions and assign their # values to the subdomains of the MixedFunctionSpace of images # Create a scalar Function Space S1 = df.FunctionSpace(self.sim.m_field.functionspace.mesh(), 'CG', 1) # Define a variable to use as vector in all the assemble instances assemble_vector = None # Define the interpolations step for theta assemble_vector = df.assemble(df.dot((theta1 - theta0) / (n + 1)) * df.dP, tensor=assemble_vector) dtheta = df.Function(S1) dtheta.vector().axpy(1, assemble_vector) # The same for Phi assemble_vector = df.assemble(df.dot((theta1 - theta0) / (n + 1)) * df.dP, tensor=assemble_vector) dphi = df.Function(S1) dphi.vector().axpy(1, assemble_vector) # Now loop for every interpolation and assign it to # the MixedFunctionSpace for i in xrange(n): # Create a dolfin function from the FS, for the interpolation interpolation_theta = df.Function(S1) interpolation_phi = df.Function(S1) # Compute the radius using the assemble method with dolfin dP # (like a dirac delta to get values on every node of the mesh) # This returns a dolfin vector # Theta assemble_vector = df.assemble(df.dot(theta0 + (i + 1) * dtheta, # df.TestFunction(S1)) * df.dP, tensor=assemble_vector ) # Set the vector values to the dolfin function interpolation_theta.vector().axpy(1, assemble_vector) # Phi assemble_vector = df.assemble(df.dot(phi0 + (i + 1) * dphi, # df.TestFunction(S1)) * df.dP, tensor=assemble_vector ) # Set the vector values to the dolfin function interpolation_phi.vector().axpy(1, assemble_vector) # Now set this interpolation to the corresponding image # Set a vector function space for the simulation # magnetisation vector field interpolation = df.VectorFunction(self.sim.S3) interpolation = df.assemble(df.dot(df.as_vector((df.sin(interpolation_theta) * df.cos(interpolation_phi), df.sin(interpolation_theta) * df.sin(interpolation_phi), df.cos(interpolation_theta) )), df.TestFunction(self.sim.S3)) * df.dP ) interpolation.vector().axpy(1, interpolation) # Now assign the interpolation vector function values to the corresponding # image in the MixedFunctionSpace df.assign(self.images_fun.sub(i), interpolation)