Hi everyone,
I’m analyzing the magneto mechanical static 2D problem of a ferromagnetic bar influenced by an electromagnet, the image below describes the geometry:
All materials are assumed isotropic and the ferromagnetic material is considered as linear. Later, I’ll try to implement the nonlinearities of the material and analyze the modal response (also seeking for advise in these matters).
When comparing with a commercial software (COMSOL) I’m getting a lot of difference in the displacement results.
Thanks for reading and any help is appreciated.
here’s the code:
from __future__ import print_function
from fenics import *
from dolfin import *
import numpy as np
from mshr import *
from math import sin, cos, pi
import matplotlib.pyplot as plt
import time
w = 0.2
h = 3.5
eh = 0.1
Ab = w * h #coil area
domain = Rectangle(Point(0, 0), Point(8, 8))
#geometry
inf_arm = Rectangle(Point(1, 2), Point(6, 1))
lef_arm = Rectangle(Point(1, 6), Point(2, 2))
sup_arm = Rectangle(Point(1, 7), Point(6, 6))
arm = Rectangle(Point(6.1, 7), Point(7.1, 1))
core = sup_arm + inf_arm + lef_arm
coil1 = Rectangle(Point(0.7, 5.7), Point(0.9, 2.2))
coil2 = Rectangle(Point(2.1, 5.7), Point(2.3, 2.2))
domain.set_subdomain(1, core)
domain.set_subdomain(2, coil1)
domain.set_subdomain(3, coil2)
domain.set_subdomain(4, arm)
mesh = generate_mesh(domain, 64)
mu_0 = 4 * pi * 1e-7
mu_ra = 1500
mu_rc = 1
class Permeability(UserExpression):
def __init__(self, markers, **kwargs):
super(Permeability, self).__init__(**kwargs)
self.markers = markers
def eval_cell(self, values, x, cell):
if self.markers[cell.index] == 0:
values[0] = mu_0 #vac perm
elif self.markers[cell.index] == 1:
values[0] = mu_ra * mu_0 # iron perm
elif self.markers[cell.index] == 4:
values[0] = mu_ra * mu_0
else:
values[0] = mu_rc * mu_0
mu = Permeability(markers, degree=1)
perm = project(mu, FunctionSpace(mesh, "DG", 0))
# current (A)
I_s = Constant(1)
I_e = Constant(-1)
# magnetostatic
VE = FunctionSpace(mesh, 'P', 2)
A_z = TrialFunction(VE)
v_E = TestFunction(VE)
aE = (1 / mu) * dot(grad(A_z), grad(v_E)) * dx
N1_s = I_s * v_E * dx(2)
N1_e = I_e * v_E * dx(3)
LE = (1 / Ab) * (N1_s + N1_e)
bcE = DirichletBC(VE, Constant(0), 'on_boundary')
Az = Function(VE)
solve(aE == LE, Az, bcE)
W = VectorFunctionSpace(mesh, 'DG', 0)
B = project(as_vector((Az.dx(1), -Az.dx(0))), W)
Bx = Az.dx(1)
By = -Az.dx(0)
Hx = Bx / mu
Hy = By / mu
Fx = mu * Hx * Hy * eh
Fy = (0.5 * mu) * (Hy ** 2 - Hx ** 2) * eh
dF = project(as_vector((Fx, Fy)), W)
f = dF
E = Constant(212E6)
nu = Constant(0.3)
lmbda = (E * nu) / ((1 + nu) * (1 - 2 * nu))
miu = E / 2 / (1 + nu)
Vi = VectorFunctionSpace(mesh, 'Lagrange', 2)
def eps(v):
return sym(grad(v))
def sigma(v):
return lmbda * tr(eps(v)) * Identity(2) + 2.0 * miu * eps(v)
class Solid(SubDomain):
def inside(self, x, on_boundary):
return between(x[0], (6.1, 7.1)) and between(x[1], (1.0, 7.0))
subdomain_marker = MeshFunction("size_t", mesh, mesh.geometry().dim(), 0)
Solid().mark(subdomain_marker, 1)
class Boundary(SubDomain):
def inside(self, x, on_boundary):
tol = 1e-14
return between(x[0], (6.1, 7.1)) and x[1] == 1
boundary_marker = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1, 0)
arm_bound = Boundary()
Boundary().mark(boundary_marker, 2)
du = TrialFunction(Vi)
u_ = TestFunction(Vi)
a = inner(sigma(du), eps(u_)) * dx(4)
fm = inner(f, u_) * dx(4)
start = time.time()
bc = DirichletBC(Vi, Constant((0, 0)), boundary_marker, 2)
u = Function(Vi, name="Displacement")
solve(a == fm, u, bc)
