Пример #1
0
 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
Пример #2
0
 def _get_form(self):
     n = self.function_space.cell().n
     k0 = self.k0
     E_i = self.E_i
     E_r = self.E_r
     mu_r = self._get_mur_function()
     return (1/k0/Z0)*dolfin.dot(n, (dolfin.cross(E_r, -dolfin.curl(E_i)/mu_r) +
                                     dolfin.cross(E_i, dolfin.curl(E_r)/mu_r)))*dolfin.ds
Пример #3
0
 def _get_form(self):
     n = self.function_space.cell().n
     k0 = self.k0
     E_i = self.E_i
     E_r = self.E_r
     mu_r = self._get_mur_function()
     return (1 / k0 / Z0) * dolfin.dot(
         n, (dolfin.cross(E_r, -dolfin.curl(E_i) / mu_r) +
             dolfin.cross(E_i,
                          dolfin.curl(E_r) / mu_r))) * dolfin.ds
Пример #4
0
def rigid_motion_term(mesh, u, r):
    position = dolfin.SpatialCoordinate(mesh)
    RM = [
        Constant((1, 0, 0)),
        Constant((0, 1, 0)),
        Constant((0, 0, 1)),
        dolfin.cross(position, Constant((1, 0, 0))),
        dolfin.cross(position, Constant((0, 1, 0))),
        dolfin.cross(position, Constant((0, 0, 1))),
    ]

    return sum(dolfin.dot(u, zi) * r[i] * dolfin.dx for i, zi in enumerate(RM))
Пример #5
0
    def __init__(self, mesh):
        self.mesh = mesh
        self.S1 = df.FunctionSpace(mesh, 'CG', 1)
        self.S3 = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3)
        #zero = df.Expression('0.3')
        m_init = df.Constant([1, 1, 1.0])
        self.m = df.interpolate(m_init, self.S3)
        self.field = df.interpolate(m_init, self.S3)
        self.dmdt = df.interpolate(m_init, self.S3)
        self.spin = self.m.vector().array()
        self.t = 0

        #It seems it's not safe to specify rank in df.interpolate???
        self._alpha = df.interpolate(df.Constant("0.001"), self.S1)
        self._alpha.vector().set_local(self._alpha.vector().array())
        print 'dolfin', self._alpha.vector().array()

        self.llg = LLG(self.S1, self.S3, unit_length=1e-9)
        #normalise doesn't work due to the wrong order
        self.llg.set_m(m_init, normalise=True)

        parameters = {
            'absolute_tolerance': 1e-10,
            'relative_tolerance': 1e-10,
            'maximum_iterations': int(1e5)
        }

        demag = Demag()

        demag.parameters['phi_1'] = parameters
        demag.parameters['phi_2'] = parameters

        self.exchange = Exchange(13e-12)
        self.zeeman = Zeeman([0, 0, 1e5])

        self.llg.effective_field.add(self.exchange)
        #self.llg.effective_field.add(demag)
        self.llg.effective_field.add(self.zeeman)

        self.m_petsc = df.as_backend_type(self.llg.m_field.f.vector()).vec()
        self.h_petsc = df.as_backend_type(self.field.vector()).vec()
        self.alpha_petsc = df.as_backend_type(self._alpha.vector()).vec()
        self.dmdt_petsc = df.as_backend_type(self.dmdt.vector()).vec()
        alpha = 0.001
        gamma = 2.21e5
        LLG1 = -gamma / (1 + alpha * alpha) * df.cross(
            self.m,
            self.field) - alpha * gamma / (1 + alpha * alpha) * df.cross(
                self.m, df.cross(self.m, self.field))
        self.L = df.dot(LLG1, df.TestFunction(self.S3)) * df.dP
Пример #6
0
def skyrmion_number_density_function(self):
    """
    This function returns the skyrmion number density function calculated
    from the spin texture in this simulation instance. This function can be
    probed to determine the local nature of the skyrmion number.
    """

    integrand = -0.25 / np.pi * df.dot(
        self.m_field.f,
        df.cross(df.Dx(self.m_field.f, 0), df.Dx(self.m_field.f, 1)))

    # Build the function space of the mesh nodes.
    dofmap = self.S3.dofmap()
    S1 = df.FunctionSpace(self.S3.mesh(),
                          "Lagrange",
                          1,
                          constrained_domain=dofmap.constrained_domain)

    # Find the skyrmion density at the mesh nodes using the above function
    # space.
    nodalSkx = df.dot(integrand, df.TestFunction(S1)) * df.dx
    nodalVolumeS1 = nodal_volume(S1, self.unit_length)
    skDensity = df.assemble(nodalSkx).array() * self.unit_length\
        ** self.S3.mesh().topology().dim() / nodalVolumeS1

    # Build the skyrmion number density dolfin function from the skDensity
    # array.
    skDensityFunc = df.Function(S1)
    skDensityFunc.vector()[:] = skDensity
    return skDensityFunc
Пример #7
0
 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
Пример #8
0
 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
Пример #9
0
def skyrmion_number(self):
    """
    This function returns the skyrmion number calculated from the spin
    texture in this simulation instance.

    If the sim object is 3D, the skyrmion number is calculated from the
    magnetisation of the top surface (since the skyrmion number formula
    is only defined for 2D).
    
    Details about computing functionals over subsets of the mesh (the 
    method used in this function to calculate the skyrmion number) can be
    found at:
    
    https://bitbucket.org/fenics-project/dolfin/src/master/demo/undocumented/lift-drag/python/demo_lift-drag.py
    """

    mesh = self.mesh

    # Get m field and define skyrmion number integrand
    m = self.m_field.f
    integrand = -0.25 / np.pi * df.dot(m, df.cross(df.Dx(m, 0), df.Dx(m, 1)))

    # determine if 3D system or not. Act accordingly.
    if self.mesh.topology().dim() == 3:
        mesh_coords = mesh.coordinates()
        z_max = max(mesh_coords[:, 2])

        # Define a subdomain which consists of the top surface of the geometry
        class Top(df.SubDomain):
            def inside(self, pt, on_boundary):
                x, y, z = pt
                return z >= z_max - df.DOLFIN_EPS and on_boundary

        # Define a set of Markers from a MeshFunction (which is a function that
        # can be evaluated at a set of mesh entities). Set all the marks to Zero.
        markers = df.MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
        markers.set_all(0)
        top = Top()
        # Redefine the marks on the top surface to 1.
        top.mark(markers, 1)
        # Define ds so that it only computes where the marker=1 (top surface)
        ds = df.ds[markers]

        # Assemble the integrand on the the original domain, but only over the
        # marked region (top surface).
        S = df.assemble(form=integrand * ds(1, domain=mesh))

    else:
        S = df.assemble(integrand * df.dx)

    return S
Пример #10
0
 def cross(self, other):
     """
     Return vector field representing the cross product of this field with `other`.
     """
     if not isinstance(other, Field):
         raise TypeError("Argument must be a Field. Got: {} ({})".format(
             other, type(other)))
     if not (self.value_dim() == 3 and other.value_dim() == 3):
         raise ValueError(
             "The cross product is only defined for 3d vector fields.")
     # We use Claas Abert's 'point measure hack' for the vertex-wise cross product.
     w = df.TestFunction(self.functionspace)
     v_res = df.assemble(df.dot(df.cross(self.f, other.f), w) * df.dP)
     return Field(self.functionspace, value=v_res)
Пример #11
0
    def get_bilinear_form(self, test_function=None, trial_function=None):
        """Calculate and return the bilinear form associated with the boundary condition.
        
        The form is calculated as: M{<n S{times} v, n S{times} u>}, where M{v} and M{u} are the 
        test and trial functions, respectively.
        
        @keyword test_function: override the stored test function space. 
            (default: None.)
        @keyword trial_function: override the stored trial function space.
            (default: None.)
        """
        V = self.function_space
        if test_function is None:
            v = dolfin.TestFunction(self.function_space)
        else:
            v = test_function
        if trial_function is None:
            u = dolfin.TrialFunction(self.function_space)
        else:
            u = trial_function

        n = V.cell().n
        s_0 = inner(cross(n, v), cross(n, u)) * ds
        return s_0
Пример #12
0
    def get_bilinear_form(self, test_function=None, trial_function=None):
        """Calculate and return the bilinear form associated with the boundary condition.
        
        The form is calculated as: M{<n S{times} v, n S{times} u>}, where M{v} and M{u} are the 
        test and trial functions, respectively.
        
        @keyword test_function: override the stored test function space. 
            (default: None.)
        @keyword trial_function: override the stored trial function space.
            (default: None.)
        """
        V = self.function_space 
        if test_function is None:
            v = dolfin.TestFunction(self.function_space)
        else:
            v = test_function
        if trial_function is None:
            u = dolfin.TrialFunction(self.function_space)
        else:
            u = trial_function

        n = V.cell().n
        s_0 = inner(cross(n, v), cross(n, u))*ds
        return s_0
Пример #13
0
 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
Пример #14
0
        beta_endo_lv=0,
        beta_epi_lv=0,
    )

    circ, _, _ = ldrb.dolfin_ldrb(
        mesh=mesh,
        fiber_space=space,
        ffun=ffun,
        markers=markers,
        alpha_endo_lv=0,
        alpha_epi_lv=0,
        beta_endo_lv=0,
        beta_epi_lv=0,
    )

    rad = dolfin.project(dolfin.cross(circ, long), circ.function_space())

#
# For the single ventricle it is much simpler
#

else:

    long, circ, rad = ldrb.dolfin_ldrb(
        mesh=mesh,
        fiber_space=space,
        ffun=ffun,
        markers=markers,
        alpha_endo_lv=-90,
        alpha_epi_lv=-90,
        beta_endo_lv=0,
Пример #15
0
for i in subIds:
    dA[i] = dlfn.Measure("ds",
                         subMeshes[i],
                         subdomain_data=facetSubMeshFuns[i])
    dV[i] = dlfn.Measure("dx", subMeshes[i])
    normals[i] = dlfn.FacetNormal(subMeshes[i])
#------------------------------------------------------------------------------#
# weak forms and assembly in interior
#------------------------------------------------------------------------------#
# linear forms in interior domain
from dolfin import curl, inner, dot, cross, grad
jumpM = dlfn.Constant((0.0, 0.0, -1.0))
a_int = inner(curl(A), curl(B)) * dV[intId]
b_int = dot(A, grad(v)) * dV[intId]
c_int = u * dot(normals[intId], curl(B)) * dA[intId](intrfcId)
l_int = dot(cross(normals[intId], jumpM), B) * dA[intId](intrfcId)
# assemble (0,0)-block
matA = dlfn.assemble(a_int)
rhs_int = dlfn.assemble(l_int)
# assemble (0,1)-block
matB = dlfn.assemble(b_int)
# assemble (0,2)-block
matC = dlfn.assemble(c_int)
#------------------------------------------------------------------------------#
# weak forms and assembly in exterior
#------------------------------------------------------------------------------#
# linear forms in exterior domain
a_ext = inner(grad(phi), grad(psi)) * dV[extId]
l_ext = dlfn.Constant(0.) * psi * dV[extId]
# apply boundary condition
bc = dlfn.DirichletBC(extH1, dlfn.Constant(0.), facetSubMeshFuns[extId],
Пример #16
0
A, phi = dlfn.TrialFunctions(Vh)
# test functions
delA, psi = dlfn.TestFunctions(Vh)
# geometric objects
n = dlfn.FacetNormal(mesh)
P = dlfn.Identity(dim) - dlfn.outer(n, n)
# Dirichlet boundary condition on exterior surface
bcA = dlfn.DirichletBC(Vh.sub(0), dlfn.Constant((0.0, 0.0, 0.0)), facetIds,
                       bndryId)
bcPhi = dlfn.DirichletBC(Vh.sub(1), dlfn.Constant(0.0), facetIds, bndryId)
# bilinear form
a = dlfn.dot(dlfn.curl(A), dlfn.curl(delA)) * dV() \
    + dlfn.dot(A, dlfn.grad(psi)) * dV() \
    + dlfn.dot(dlfn.grad(phi), delA) * dV()
# rhs form
l = dlfn.dot(dlfn.cross(n("+"), jumpM("+")), delA("+")) * dA(intrfcId)
# compute solution
sol = dlfn.Function(Vh)
lin_problem = dlfn.LinearVariationalProblem(a, l, sol, bcs=[bcA, bcPhi])
lin_solver = dlfn.LinearVariationalSolver(lin_problem)
lin_solver_parameters = lin_solver.parameters
lin_solver.solve()
# sub solutions
solA = sol.sub(0)
solPhi = sol.sub(1)
# output to pvd
pvd_A = dlfn.File("solution-A.pvd")
pvd_A << solA
# solving for magnetic field
Wh = dlfn.VectorFunctionSpace(mesh, "CG", 1)
curlA = dlfn.project(dlfn.curl(solA), Wh)
Пример #17
0
# Define function space
order = 1
V = dol.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", order)

# Define basis and bilinear form
k_0 = 2*N.pi*freq/c0

u = dol.TrialFunction(V)
v = dol.TestFunction(V)

m = eps_r*inner(v, u)*dx                  # Mass form
s = (1/mu_r)*dot(curl(v), curl(u))*dx            # Stiffness form

n = V.cell().n
s_0 = inner ( cross ( n, v), cross ( n, u ) )*ds

def boundary(x, on_boundary):
    return on_boundary

# Assemble forms
M = dol.uBLASSparseMatrix()
S = dol.uBLASSparseMatrix()
S_0 = dol.uBLASSparseMatrix()

dol.assemble(m, tensor=M, mesh=mesh)
dol.assemble(s, tensor=S, mesh=mesh)
dol.assemble(s_0, tensor=S_0, mesh=mesh)

from scipy.sparse import csr_matrix
from pyamg import smoothed_aggregation_solver
Пример #18
0
def main():

    # Define mesh
    domain_subdivisions = N.array(
        N.ceil(N.sqrt(2) * domain_size / max_edge_len), N.uint)
    print 'Numer of domain subdomain_subdivisions: ', domain_subdivisions

    mesh = dolfin.UnitCube(*domain_subdivisions)
    # Transform mesh to correct dimensions
    mesh.coordinates()[:] *= domain_size
    # Centred around [0,0,0]
    mesh.coordinates()[:] -= domain_size / 2
    ## Translate mesh slightly so that source coordinate lies at
    ## centroid of an element

    io = mesh.intersection_operator()
    source_elnos = io.all_intersected_entities(source_point)
    closest_elno = source_elnos[(N.argmin([
        source_point.distance(dolfin.Cell(mesh, i).midpoint())
        for i in source_elnos
    ]))]
    centre_pt = dolfin.Cell(mesh, closest_elno).midpoint()
    centre_coord = N.array([centre_pt.x(), centre_pt.y(), centre_pt.z()])
    # There seems to be an issue with the intersect operator if the
    # mesh coordinates are changed after calling it for the first
    # time. Since we called it to find the centroid, we should init a
    # new mesh
    mesh_coords = mesh.coordinates().copy()
    mesh = dolfin.UnitCube(*domain_subdivisions)
    mesh.coordinates()[:] = mesh_coords
    mesh.coordinates()[:] -= centre_coord
    ##

    # Define function space
    V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", order)

    k_0 = 2 * N.pi * freq / c0  # Freespace wave number
    # Definite test- and trial functions
    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # Define the bilinear forms
    m = eps_r * inner(v, u) * dx  # Mass form
    s = (1 / mu_r) * dot(curl(v), curl(u)) * dx  # Stiffness form

    n = V.cell().n  # Get the surface normal
    s_0 = inner(cross(n, v), cross(n, u)) * ds  # ABC boundary condition form

    # Assemble forms using uBLASS matrices so that we can easily export to scipy
    print 'Assembling forms'
    M = dolfin.uBLASSparseMatrix()
    S = dolfin.uBLASSparseMatrix()
    S_0 = dolfin.uBLASSparseMatrix()
    dolfin.assemble(m, tensor=M, mesh=mesh)
    dolfin.assemble(s, tensor=S, mesh=mesh)
    dolfin.assemble(s_0, tensor=S_0, mesh=mesh)
    print 'Number of degrees of freedom: ', M.size(0)

    # Set up RHS
    b = N.zeros(M.size(0), dtype=N.complex128)

    dofnos, rhs_contrib = calc_pointsource_contrib(V, source_coord,
                                                   source_value)

    rhs_contrib = 1j * k_0 * Z0 * rhs_contrib
    b[dofnos] += rhs_contrib

    Msp = dolfin_ublassparse_to_scipy_csr(M)
    Ssp = dolfin_ublassparse_to_scipy_csr(S)
    S_0sp = dolfin_ublassparse_to_scipy_csr(S_0)

    # A is the system matrix that must be solved
    A = Ssp - k_0**2 * Msp + 1j * k_0 * S_0sp

    solved = False
    if solver == 'iterative':
        # solve using scipy bicgstab
        print 'solve using scipy bicgstab'
        x = solve_sparse_system(A, b)
    elif solver == 'direct':
        import scipy.sparse.linalg
        A_lu = scipy.sparse.linalg.factorized(A.T)
        x = A_lu(b)
    else:
        raise ValueError("solver must have value 'iterative' or 'direct'")

    dolfin.set_log_active(False)  # evaluation seems to make a lot of noise
    u_re = dolfin.Function(V)
    u_im = dolfin.Function(V)
    # N.require is important, since dolfin seems to expect a contiguous array
    u_re.vector()[:] = N.require(N.real(x), requirements='C')
    u_im.vector()[:] = N.require(N.imag(x), requirements='C')
    E_field = N.zeros((len(field_pts), 3), dtype=N.complex128)
    for i, fp in enumerate(field_pts):
        try:
            E_field[i, :] = u_re(fp) + 1j * u_im(fp)
        except (RuntimeError, StandardError):
            E_field[i, :] = N.nan + 1j * N.nan

    import pylab as P
    r1 = field_pts[:] / lam
    x1 = r1[:, 0]
    E_ana = N.abs(analytical_result)
    E_num = E_field
    P.figure()
    P.plot(x1, N.abs(E_num[:, 0]), '-g', label='x_num')
    P.plot(x1, N.abs(E_num[:, 1]), '-b', label='y_num')
    P.plot(x1, N.abs(E_num[:, 2]), '-r', label='z_num')
    P.plot(analytical_pts, E_ana, '--r', label='z_ana')
    P.ylabel('E-field Magnitude')
    P.xlabel('Distance (wavelengths)')
    P.legend(loc='best')
    P.grid(True)
    P.show()
Пример #19
0
 def as_real_imag(self, deep=True, **hints):
     u_re, u_im = self.args[0].as_real_imag()
     v_re, v_im = self.args[1].as_real_imag()
     return (cross(u_re, v_re) - cross(u_im, v_im),
             cross(u_re, v_im) + cross(v_re, u_im))
 def _setup_implicit_problem(self):
     assert hasattr(self, "_parameters")
     assert hasattr(self, "_mesh")
     assert hasattr(self, "_Wh")
     assert hasattr(self, "_coefficients")
     assert hasattr(self, "_one")
     assert hasattr(self, "_omega")
     assert hasattr(self, "_v0")
     assert hasattr(self, "_v00")
     assert hasattr(self, "_T0")
     assert hasattr(self, "_T00")
     print "   setup implicit problem..."
     #=======================================================================
     # retrieve imex coefficients
     a, c = self._imex_alpha, self._imex_gamma
     #=======================================================================
     # trial and test function
     (del_v, del_p, del_T) = dlfn.TestFunctions(self._Wh)
     v, p, T = dlfn.split(self._sol)
     # volume element
     dV = dlfn.Measure("dx", domain=self._mesh)
     # reference to time step
     timestep = self._timestep
     #=======================================================================
     from dolfin import dot, grad
     # 1) momentum equation
     momentum_eqn = (
         dot((a[0] * v + a[1] * self._v0 + a[2] * self._v00) / timestep,
             del_v) + dot(dot(grad(v), v), del_v) + self._coefficients[1] *
         a_op(c[0] * v + c[1] * self._v0 + c[2] * self._v00, del_v) -
         b_op(del_v, p) - b_op(v, del_p)) * dV
     # 2) momentum equation: coriolis term
     if self._parameters.rotation is True:
         assert self._coefficients[0] != 0.0
         print "   adding rotation to the model..."
         # add Coriolis term
         if self._space_dim == 2:
             momentum_eqn += self._coefficients[0] * (-v[1] * del_v[0] +
                                                      v[0] * del_v[1]) * dV
         elif self._space_dim == 3:
             assert hasattr(self, "_rotation_vector")
             assert isinstance(self._rotation_vector,
                               (dlfn.Constant, dlfn.Expression))
             from dolfin import cross
             momentum_eqn += self._coefficients[0] * dot(
                 cross(self._rotation_vector, v), del_v) * dV
     # 3) momentum equation: coriolis term
     if self._parameters.buoyancy is True:
         assert self._coefficients[2] != 0.0
         assert hasattr(self, "_gravity") and isinstance(
             self._gravity, (dlfn.Expression, dlfn.Constant))
         print "   adding buoyancy to the model..."
         # add buoyancy term
         momentum_eqn += self._coefficients[2] * T * dot(
             self._gravity, del_v) * dV
     #=======================================================================
     # 4) energy equation
     energy_eqn = (
         (a[0] * T + a[1] * self._T0 + a[2] * self._T00) / timestep * del_T
         + dot(v, grad(T)) * del_T + self._coefficients[3] *
         a_op(c[0] * T + c[1] * self._T0 + c[2] * self._T00, del_T)) * dV
     #=======================================================================
     # full problem
     self._eqn = momentum_eqn + energy_eqn
     if not hasattr(self, "_dirichlet_bcs"):
         self._setup_boundary_conditons()
     self._jacobian = dlfn.derivative(self._eqn, self._sol)
     problem = dlfn.NonlinearVariationalProblem(self._eqn,
                                                self._sol,
                                                J=self._jacobian,
                                                bcs=self._dirichlet_bcs)
     self._solver = dlfn.NonlinearVariationalSolver(problem)
     prm = self._solver.parameters
     prm["newton_solver"]["absolute_tolerance"] = 1e-6
     prm["newton_solver"]["relative_tolerance"] = 1e-9
     prm["newton_solver"]["maximum_iterations"] = 10
    def _setup_imex_problem(self):
        assert hasattr(self, "_parameters")
        assert hasattr(self, "_mesh")
        assert hasattr(self, "_Wh")
        assert hasattr(self, "_coefficients")
        assert hasattr(self, "_one")
        assert hasattr(self, "_omega")
        assert hasattr(self, "_v0")
        assert hasattr(self, "_v00")
        assert hasattr(self, "_T0")
        assert hasattr(self, "_T00")
        print "   setup explicit imex problem..."
        #=======================================================================
        # retrieve imex coefficients
        a, b, c = self._imex_alpha, self._imex_beta, self._imex_gamma
        #=======================================================================
        # trial and test function
        (del_v, del_p, del_T) = dlfn.TestFunctions(self._Wh)
        (dv, dp, dT) = dlfn.TrialFunctions(self._Wh)
        # volume element
        dV = dlfn.Measure("dx", domain=self._mesh)
        # reference to time step
        timestep = self._timestep
        #=======================================================================
        from dolfin import dot, grad, inner
        # 1) lhs momentum equation
        lhs_momentum = a[0] / timestep * dot(dv, del_v) *  dV \
                     + c[0] * self._coefficients[1] * a_op(dv, del_v) * dV\
                     - b_op(del_v, dp) * dV\
                     - b_op(dv, del_p) * dV
        # 2a) rhs momentum equation: time derivative
        rhs_momentum = -dot(
            a[1] / timestep * self._v0 + a[2] / timestep * self._v00,
            del_v) * dV
        # 2b) rhs momentum equation: nonlinear term
        nonlinear_term_velocity =  b[0] * dot(grad(self._v0), self._v0) \
                                 + b[1] * dot(grad(self._v00), self._v00)
        rhs_momentum -= dot(nonlinear_term_velocity, del_v) * dV
        # 2c) rhs momentum equation: linear term
        rhs_momentum -= self._coefficients[1] * inner(
            c[1] * grad(self._v0) + c[2] * grad(self._v00), grad(del_v)) * dV
        # 2d) rhs momentum equation: coriolis term
        if self._parameters.rotation is True:
            assert self._coefficients[0] != 0.0
            print "   adding rotation to the model..."
            # defining extrapolated velocity
            extrapolated_velocity = (self._one + self._omega) * self._v0 \
                                    - self._omega * self._v00
            # set Coriolis term
            if self._space_dim == 2:
                rhs_momentum -= self._coefficients[0] * (
                    -extrapolated_velocity[1] * del_v[0] +
                    extrapolated_velocity[0] * del_v[1]) * dV
            elif self._space_dim == 3:
                from dolfin import cross
                coriolis_term = cross(self._rotation_vector,
                                      extrapolated_velocity)
                rhs_momentum -= self._coefficients[0] * dot(
                    coriolis_term, del_v) * dV
            print "   adding rotation to the model..."

        # 2e) rhs momentum equation: buoyancy term
        if self._parameters.buoyancy is True:
            assert self._coefficients[2] != 0.0
            # defining extrapolated temperature
            extrapolated_temperature = (
                self._one + self._omega) * self._T0 - self._omega * self._T00
            # buoyancy term
            print "   adding buoyancy to the model..."
            rhs_momentum -= self._coefficients[
                2] * extrapolated_temperature * dot(self._gravity, del_v) * dV
        #=======================================================================
        # 3) lhs energy equation
        lhs_energy = a[0] / timestep * dot(dT, del_T) * dV \
                   + self._coefficients[3] * a_op(dT, del_T) * dV
        # 4a) rhs energy equation: time derivative
        rhs_energy = -dot(
            a[1] / timestep * self._T0 + a[2] / timestep * self._T00,
            del_T) * dV
        # 4b) rhs energy equation: nonlinear term
        nonlinear_term_temperature =  b[0] * dot(self._v0, grad(self._T0)) \
                                    + b[1] * dot(self._v00, grad(self._T00))
        rhs_energy -= nonlinear_term_temperature * del_T * dV
        # 4c) rhs energy equation: linear term
        rhs_energy -= self._coefficients[3] \
                        * dot(c[1] * grad(self._T0) + c[2] * grad(self._T00), grad(del_T)) * dV
        #=======================================================================
        # full problem
        self._lhs = lhs_momentum + lhs_energy
        self._rhs = rhs_momentum + rhs_energy
        if not hasattr(self, "_dirichlet_bcs"):
            self._setup_boundary_conditions()
        if self._parameters.use_assembler_method:
            # system assembler
            self._assembler = dlfn.SystemAssembler(self._lhs,
                                                   self._rhs,
                                                   bcs=self._dirichlet_bcs)
            self._system_matrix = dlfn.Matrix()
            self._system_rhs = dlfn.Vector()
            self._solver = dlfn.LUSolver(self._system_matrix)
        else:
            # linear problem
            problem = dlfn.LinearVariationalProblem(self._lhs,
                                                    self._rhs,
                                                    self._sol,
                                                    bcs=self._dirichlet_bcs)
            self._solver = dlfn.LinearVariationalSolver(problem)
Пример #22
0
def main():

    # Define mesh
    domain_subdivisions = N.array(N.ceil(N.sqrt(2)*domain_size/max_edge_len), N.uint)
    print 'Numer of domain subdomain_subdivisions: ', domain_subdivisions

    mesh = dolfin.UnitCube(*domain_subdivisions)
    # Transform mesh to correct dimensions
    mesh.coordinates()[:] *= domain_size
    # Centred around [0,0,0]
    mesh.coordinates()[:] -= domain_size/2
    ## Translate mesh slightly so that source coordinate lies at
    ## centroid of an element
    source_elnos = mesh.all_intersected_entities(source_point)
    closest_elno = source_elnos[(N.argmin([source_point.distance(dolfin.Cell(mesh, i).midpoint())
                                  for i in source_elnos]))]
    centre_pt = dolfin.Cell(mesh, closest_elno).midpoint()
    centre_coord = N.array([centre_pt.x(), centre_pt.y(), centre_pt.z()])
    # There seems to be an issue with the intersect operator if the
    # mesh coordinates are changed after calling it for the first
    # time. Since we called it to find the centroid, we should init a
    # new mesh
    mesh_coords = mesh.coordinates().copy()
    mesh = dolfin.UnitCube(*domain_subdivisions)
    mesh.coordinates()[:] = mesh_coords
    mesh.coordinates()[:] -= centre_coord
    ##

    # Define function space
    V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", order)

    k_0 = 2*N.pi*freq/c0                    # Freespace wave number
    # Definite test- and trial functions
    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # Define the bilinear forms
    m = eps_r*inner(v, u)*dx                # Mass form
    s = (1/mu_r)*dot(curl(v), curl(u))*dx   # Stiffness form

    n = V.cell().n                           # Get the surface normal
    s_0 = inner(cross(n, v), cross(n, u))*ds # ABC boundary condition form

    # Assemble forms using uBLASS matrices so that we can easily export to scipy
    print 'Assembling forms'
    M = dolfin.uBLASSparseMatrix()
    S = dolfin.uBLASSparseMatrix()
    S_0 = dolfin.uBLASSparseMatrix()
    dolfin.assemble(m, tensor=M, mesh=mesh)
    dolfin.assemble(s, tensor=S, mesh=mesh)
    dolfin.assemble(s_0, tensor=S_0, mesh=mesh)
    print 'Number of degrees of freedom: ', M.size(0)


    # Set up RHS
    b = N.zeros(M.size(0), dtype=N.complex128)
    dofnos, rhs_contrib = calc_pointsource_contrib(V, source_coord, source_value)

    rhs_contrib = 1j*k_0*Z0*rhs_contrib
    b[dofnos] += rhs_contrib

    Msp = dolfin_ublassparse_to_scipy_csr(M)
    Ssp = dolfin_ublassparse_to_scipy_csr(S)
    S_0sp = dolfin_ublassparse_to_scipy_csr(S_0)

    # A is the system matrix that must be solved
    A = Ssp - k_0**2*Msp + 1j*k_0*S_0sp     


    solved = False;
    if solver == 'iterative':
        # solve using scipy bicgstab
        print 'solve using scipy bicgstab'
        x = solve_sparse_system ( A, b )
    elif solver == 'direct':
        import scipy.sparse.linalg
        A_lu = scipy.sparse.linalg.factorized(A.T)
        x = A_lu(b)
    else: raise ValueError("solver must have value 'iterative' or 'direct'")

    dolfin.set_log_active(False) # evaluation seems to make a lot of noise
    u_re = dolfin.Function(V)
    u_im = dolfin.Function(V)
    # N.require is important, since dolfin seems to expect a contiguous array
    u_re.vector()[:] = N.require(N.real(x), requirements='C')
    u_im.vector()[:] = N.require(N.imag(x), requirements='C')
    E_field = N.zeros((len(field_pts), 3), dtype=N.complex128)
    for i, fp in enumerate(field_pts):
        try: E_field[i,:] = u_re(fp) + 1j*u_im(fp)
        except (RuntimeError, StandardError): E_field[i,:] = N.nan + 1j*N.nan

    import pylab as P
    r1 = field_pts[:]/lam
    x1 = r1[:,0]
    E_ana = N.abs(analytical_result)
    E_num = E_field
    P.figure()
    P.plot(x1, N.abs(E_num[:,0]), '-g', label='x_num')
    P.plot(x1, N.abs(E_num[:,1]), '-b', label='y_num')
    P.plot(x1, N.abs(E_num[:,2]), '-r', label='z_num')
    P.plot(analytical_pts, E_ana, '--r', label='z_ana')
    P.ylabel('E-field Magnitude')
    P.xlabel('Distance (wavelengths)')
    P.legend(loc='best')
    P.grid(True)
    P.show()
Пример #23
0
def cross_product(a, b, S3):
    """
    Function computing the cross product of two vector functions.
    The result is a dolfin vector.
    """
    return df.assemble(df.dot(df.cross(a, b), df.TestFunction(S3)) * df.dP)
Пример #24
0
def generate_matrices(mesh_file, order):
    """
    Generate the matrices for a 1\lambda spherical domain with an infintesimal dipole at the origin.
    
    @param mesh_file: the full path and filename to the spherical mesh to be used (this is a femmesh file).
    @todo: change the mesh type to a gmsh mesh.
    """
    problem_data = {
        'l': 2.9979245800000002e-4,
        'I': 1.0,
        'f': 1.0e9,
        'source_coord': np.array([0, 0, 0.]),
        'order': order,
    }

    lam = c0 / problem_data['f']

    # load the mesh and scale coordinates accordingly
    mesh = femmesh_2_dolfin_mesh(mesh_file)
    mesh.init()
    mesh.coordinates()[:] *= lam

    eps_r = 1
    mu_r = 1
    freq = problem_data['f']
    source_coord = problem_data['source_coord']
    source_point = dolfin.Point(*source_coord)
    source_value = np.array([0, 0, 1.]) * problem_data['I'] * problem_data['l']

    V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)",
                             problem_data['order'])
    print 'DOFs: ', V.dim()

    # Define basis and bilinear form
    k_0 = 2 * np.pi * freq / c0

    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    m = eps_r * inner(v, u) * dx  # Mass form
    s = (1 / mu_r) * dot(curl(v), curl(u)) * dx  # Stiffness form

    n = V.cell().n
    s_0 = inner(cross(n, v), cross(n, u)) * ds

    def boundary(x, on_boundary):
        return on_boundary

    # Assemble forms
    print 'assembling forms'
    M = dolfin.uBLASSparseMatrix()
    S = dolfin.uBLASSparseMatrix()
    S_0 = dolfin.uBLASSparseMatrix()
    dolfin.assemble(m, tensor=M, mesh=mesh)
    dolfin.assemble(s, tensor=S, mesh=mesh)
    dolfin.assemble(s_0, tensor=S_0, mesh=mesh)

    # Set up RHS
    b = np.zeros(M.size(0), dtype=np.complex128)
    dofnos, rhs_contrib = point_source.calc_pointsource_contrib(
        V, source_coord, source_value)

    rhs_contrib = 1j * k_0 * Z0 * rhs_contrib
    b[dofnos] += rhs_contrib

    Msp = dolfin_ublassparse_to_scipy_csr(M)
    Ssp = dolfin_ublassparse_to_scipy_csr(S)
    S_0sp = dolfin_ublassparse_to_scipy_csr(S_0)
    A = Ssp - k_0**2 * Msp + 1j * k_0 * S_0sp

    return A, b
def Cost(xp):
    comm = nMPI.COMM_WORLD
    mpi_rank = comm.Get_rank()

    x1, x2 = xp #The two variables (length and feed offset)

    rs = 8.0  # radiation boundary radius
    l = x1  # Patch length
    w = 4.5  # Patch width
    s1 = x2 * x1 / 2.0  # Feed offset
    h = 1.0   # Patch height
    t = 0.05   # Metal thickness
    lc = 1.0  # Coax length
    rc = 0.25 # Coax shield radius
    cc = 0.107 #Coax center conductor 50 ohm air diel
    eps = 1.0e-4
    tol = 1.0e-6
    eta = 377.0 # vacuum intrinsic wave impedance
    eps_c = 1.0 # dielectric permittivity

    k0 = 2.45 * 2.0 * np.pi / 30.0 # Frequency in GHz
    ls = 0.025 #Mesh density parameters for GMSH
    lm = 0.8
    lw = 0.06
    lp = 0.3

    # Run GMSH only on one MPI processor (process 0).
    # We use the GMSH Python interface to generate the geometry and mesh objects
    if mpi_rank == 0:
        print("x[0] = {0:<f}, x[1] = {1:<f} ".format(xp[0], xp[1]))
        print("length = {0:<f}, width = {1:<f}, feed offset = {2:<f}".format(l, w, s1))
        gmsh.initialize()
        gmsh.option.setNumber('General.Terminal', 1)
        gmsh.model.add("SimplePatchOpt")
# Radiation sphere
        gmsh.model.occ.addSphere(0.0, 0.0, 0.0, rs, 1)
        gmsh.model.occ.addBox(0.0, -rs, 0.0, rs, 2*rs, rs, 2)
        gmsh.model.occ.intersect([(3,1)],[(3,2)], 3, removeObject=True, removeTool=True)
# Patch
        gmsh.model.occ.addBox(0.0, -l/2, h, w/2, l, t, 4)
# coax center
        gmsh.model.occ.addCylinder(0.0, s1, -lc, 0.0, 0.0, lc+h, cc, 5, 2.0*np.pi)

# coax shield
        gmsh.model.occ.addCylinder(0.0, s1, -lc, 0.0, 0.0, lc, rc, 7)
        gmsh.model.occ.addBox(0.0, s1-rc, -lc, rc, 2.0*rc, lc, 8)
        gmsh.model.occ.intersect([(3,7)], [(3,8)], 9, removeObject=True, removeTool=True)
        gmsh.model.occ.fuse([(3,3)], [(3,9)], 10, removeObject=True, removeTool=True)
# cutout internal boundaries
        gmsh.model.occ.cut([(3,10)], [(3,4),(3,5)], 11, removeObject=True, removeTool=True)

        gmsh.option.setNumber('Mesh.MeshSizeMin', ls)
        gmsh.option.setNumber('Mesh.MeshSizeMax', lm)
        gmsh.option.setNumber('Mesh.Algorithm', 6)
        gmsh.option.setNumber('Mesh.Algorithm3D', 1)
        gmsh.option.setNumber('Mesh.MshFileVersion', 4.1)
        gmsh.option.setNumber('Mesh.Format', 1)
        gmsh.option.setNumber('Mesh.MinimumCirclePoints', 36)
        gmsh.option.setNumber('Mesh.CharacteristicLengthFromCurvature', 1)

        gmsh.model.occ.synchronize()

        pts = gmsh.model.getEntities(0)
        gmsh.model.mesh.setSize(pts, lm) #Set background mesh density
        pts = gmsh.model.getEntitiesInBoundingBox(-eps, -l/2-eps, h-eps, w/2+eps, l/2+eps, h+t+eps)
        gmsh.model.mesh.setSize(pts, ls)

        pts = gmsh.model.getEntitiesInBoundingBox(-eps, s1-rc-eps, -lc-eps, rc+eps, s1+rc+eps, h+eps)
        gmsh.model.mesh.setSize(pts, lw)
        pts = gmsh.model.getEntitiesInBoundingBox(-eps, -rc-eps, -eps, rc+eps, rc+eps, eps)
        gmsh.model.mesh.setSize(pts, lw)

# Embed points to reduce mesh density on patch faces
        fce1 = gmsh.model.getEntitiesInBoundingBox(-eps, -l/2-eps, h+t-eps, w/2+eps, l/2+eps, h+t+eps, 2)
        gmsh.model.occ.synchronize()
        gmsh.model.geo.addPoint(w/4, -l/4, h+t, lp, 1000)
        gmsh.model.geo.addPoint(w/4, 0.0, h+t, lp, 1001)
        gmsh.model.geo.addPoint(w/4, l/4, h+t, lp, 1002)
        gmsh.model.geo.synchronize()
        gmsh.model.occ.synchronize()
        print(fce1)
        fce2 = gmsh.model.getEntitiesInBoundingBox(-eps, -l/2-eps, h-eps, w/2+eps, l/2+eps, h+eps, 2)
        gmsh.model.geo.addPoint(w/4, -9*l/32, h, lp, 1003)
        gmsh.model.geo.addPoint(w/4, 0.0, h, lp, 1004)
        gmsh.model.geo.addPoint(w/4, 9*l/32, h, lp, 1005)
        gmsh.model.geo.synchronize()
        for tt in fce1:
           gmsh.model.mesh.embed(0, [1000, 1001, 1002], 2, tt[1])
        for tt in fce2:
           gmsh.model.mesh.embed(0, [1003, 1004, 1005], 2, tt[1])
        print(fce2)
        gmsh.model.occ.remove(fce1)
        gmsh.model.occ.remove(fce2)
        gmsh.model.occ.synchronize()
        gmsh.model.addPhysicalGroup(3, [11], 1)
        gmsh.model.setPhysicalName(3, 1, "Air")
        gmsh.model.mesh.optimize("Relocate3D", niter=5)
        gmsh.model.mesh.generate(3)
        gmsh.write("SimplePatch.msh")
        gmsh.finalize()
# Mesh generation is finished.  We now use Meshio to translate GMSH mesh to xdmf file for 
# importation into Fenics FE solver
        msh = meshio.read("SimplePatch.msh")
        for cell in msh.cells:
            if  cell.type == "tetra":
                tetra_cells = cell.data

        for key in msh.cell_data_dict["gmsh:physical"].keys():
            if key == "tetra":
                tetra_data = msh.cell_data_dict["gmsh:physical"][key]

        tetra_mesh = meshio.Mesh(points=msh.points, cells={"tetra": tetra_cells},
                           cell_data={"VolumeRegions":[tetra_data]})

        meshio.write("mesh.xdmf", tetra_mesh)
# Here we import the mesh into Fenics
    mesh = dolfin.Mesh()
    with dolfin.XDMFFile("mesh.xdmf") as infile:
        infile.read(mesh)
    mvc = dolfin.MeshValueCollection("size_t", mesh, 3)
    with dolfin.XDMFFile("mesh.xdmf") as infile:
        infile.read(mvc, "VolumeRegions")
    cf = dolfin.cpp.mesh.MeshFunctionSizet(mesh, mvc)
# The boundary classes for the FE solver
    class PEC(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary

    class InputBC(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and dolfin.near(x[2], -lc, tol)

    class OutputBC(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            rr = np.sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
            return on_boundary and dolfin.near(rr, 8.0, 1.0e-1)

    class PMC(dolfin.SubDomain):
        def inside(self, x, on_boundary):
            return on_boundary and dolfin.near(x[0], 0.0, tol)


# Volume domains
    dolfin.File("VolSubDomains.pvd").write(cf)
    dolfin.File("Mesh.pvd").write(mesh)
# Mark boundaries
    sub_domains = dolfin.MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
    sub_domains.set_all(4)
    pec = PEC()
    pec.mark(sub_domains, 0)
    in_port = InputBC()
    in_port.mark(sub_domains, 1)
    out_port = OutputBC()
    out_port.mark(sub_domains, 2)
    pmc = PMC()
    pmc.mark(sub_domains, 3)
    dolfin.File("BoxSubDomains.pvd").write(sub_domains)
# Set up function spaces
    cell = dolfin.tetrahedron
    ele_type = dolfin.FiniteElement('N1curl', cell, 2, variant="integral") # H(curl) element for EM
    V2 = dolfin.FunctionSpace(mesh, ele_type * ele_type)
    V = dolfin.FunctionSpace(mesh, ele_type)
    (u_r, u_i) = dolfin.TrialFunctions(V2)
    (v_r, v_i) = dolfin.TestFunctions(V2)
    dolfin.info(mesh)
#surface integral definitions from boundaries
    ds = dolfin.Measure('ds', domain = mesh, subdomain_data = sub_domains)
#volume regions
    dx_air = dolfin.Measure('dx', domain = mesh, subdomain_data = cf, subdomain_id = 1)
    dx_subst = dolfin.Measure('dx', domain = mesh, subdomain_data = cf, subdomain_id = 2)
# with source and sink terms
    u0 = dolfin.Constant((0.0, 0.0, 0.0)) #PEC definition
# The incident field sources (E and H-fields)
    h_src = dolfin.Expression(('-(x[1] - s) / (2.0 * pi * (pow(x[0], 2.0) + pow(x[1] - s,2.0)))', 'x[0] / (2.0 * pi *(pow(x[0],2.0) + pow(x[1] - s,2.0)))', 0.0), degree = 2,  s = s1)
    e_src = dolfin.Expression(('x[0] / (2.0 * pi * (pow(x[0], 2.0) + pow(x[1] - s,2.0)))', 'x[1] / (2.0 * pi *(pow(x[0],2.0) + pow(x[1] - s,2.0)))', 0.0), degree = 2, s = s1)
    Rrad = dolfin.Expression(('sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2])'), degree = 2)
#Boundary condition dictionary
    boundary_conditions = {0: {'PEC' : u0},
                       1: {'InputBC': (h_src)},
                       2: {'OutputBC': Rrad}}

    n = dolfin.FacetNormal(mesh)

#Build PEC boundary conditions for real and imaginary parts
    bcs = []
    for i in boundary_conditions:
        if 'PEC' in boundary_conditions[i]:
            bc = dolfin.DirichletBC(V2.sub(0), boundary_conditions[i]['PEC'], sub_domains, i)
            bcs.append(bc)
            bc = dolfin.DirichletBC(V2.sub(1), boundary_conditions[i]['PEC'], sub_domains, i)
            bcs.append(bc)

# Build input BC source term and loading term
    integral_source = []
    integrals_load =[]
    for i in boundary_conditions:
        if 'InputBC' in boundary_conditions[i]:
            r = boundary_conditions[i]['InputBC']
            bb1 = 2.0 * (k0 * eta) * dolfin.inner(v_i, dolfin.cross(n, r)) * ds(i) #Factor of two from field equivalence principle
            integral_source.append(bb1)
            bb2 = dolfin.inner(dolfin.cross(n, v_i), dolfin.cross(n, u_r)) * k0 * np.sqrt(eps_c) * ds(i)
            integrals_load.append(bb2)
            bb2 = dolfin.inner(-dolfin.cross(n, v_r), dolfin.cross(n, u_i)) * k0 * np.sqrt(eps_c) * ds(i)
            integrals_load.append(bb2)

    for i in boundary_conditions:
        if 'OutputBC' in boundary_conditions[i]:
           r = boundary_conditions[i]['OutputBC']
           bb2 = (dolfin.inner(dolfin.cross(n, v_i), dolfin.cross(n, u_r)) * k0 + 1.0 * dolfin.inner(dolfin.cross(n, v_i), dolfin.cross(n, u_i)) / r)* ds(i)
           integrals_load.append(bb2)
           bb2 = (dolfin.inner(-dolfin.cross(n, v_r), dolfin.cross(n, u_i)) * k0 + 1.0 * dolfin.inner(dolfin.cross(n, v_r), dolfin.cross(n, u_r)) / r)* ds(i)
           integrals_load.append(bb2)
# for PMC, do nothing. Natural BC.

    a = (dolfin.inner(dolfin.curl(v_r), dolfin.curl(u_r)) + dolfin.inner(dolfin.curl(v_i), dolfin.curl(u_i)) - eps_c * k0 * k0 * (dolfin.inner(v_r, u_r) + dolfin.inner(v_i, u_i))) * dx_subst + (dolfin.inner(dolfin.curl(v_r), dolfin.curl(u_r)) + dolfin.inner(dolfin.curl(v_i), dolfin.curl(u_i)) - k0 * k0 * (dolfin.inner(v_r, u_r) + dolfin.inner(v_i, u_i))) * dx_air + sum(integrals_load)
    L = sum(integral_source)

    u1 = dolfin.Function(V2)
    vdim = u1.vector().size()
    print("Solution vector size =", vdim)

    dolfin.solve(a == L, u1, bcs, solver_parameters = {'linear_solver' : 'mumps'}) 

#Here we write files of the field solution for inspection
    u1_r, u1_i = u1.split(True)
    fp = dolfin.File("EField_r.pvd")
    fp << u1_r
    fp = dolfin.File("EField_i.pvd")
    fp << u1_i
# Compute power relationships and reflection coefficient
    H = dolfin.interpolate(h_src, V) # Get input field
    P =  dolfin.assemble((-dolfin.dot(u1_r,dolfin.cross(dolfin.curl(u1_i),n))+dolfin.dot(u1_i,dolfin.cross(dolfin.curl(u1_r),n))) * ds(2))
    P_refl = dolfin.assemble((-dolfin.dot(u1_i,dolfin.cross(dolfin.curl(u1_r), n)) + dolfin.dot(u1_r, dolfin.cross(dolfin.curl(u1_i), n))) * ds(1))
    P_inc = dolfin.assemble((dolfin.dot(H, H) * eta / (2.0 * np.sqrt(eps_c))) * ds(1))
    print("Integrated power on port 2:", P/(2.0 * k0 * eta))
    print("Incident power at port 1:", P_inc)
    print("Integrated reflected power on port 1:", P_inc - P_refl / (2.0 * k0 * eta))
#Reflection coefficient is returned as cost function
    rho_old = (P_inc - P_refl / (2.0 * k0 * eta)) / P_inc #Fraction of incident power reflected as objective function
    return rho_old
Пример #26
0
    def setup_kinematics(self):
        from dolfin import cross, sqrt, dot
        if self.nsd == 2:
            # Get the dual basis
            self.Gsup1 = self.Gsub1 / dot(self.Gsub1, self.Gsub1)
            R = as_tensor([[0, -1], [1, 0]])

            self.gsub1 = self.Gsub1 + self.u.dx(0)
            gradu = outer(self.u.dx(0), self.Gsup1)

            I = Identity(self.nsd)
            self.F = I + gradu
            self.C = dot(self.F.T, self.F)

            self.Gsub3 = dot(R, self.Gsub1)
            self.gsub3 = dot(R, self.gsub1)
            lmbda = sqrt(
                dot(self.gsub1, self.gsub1) / dot(self.Gsub1, self.Gsub1))
            self.lambda1, self.lambda2 = lmbda, lmbda
            self.lambda3 = 1 / self.lambda1

        elif self.nsd == 3:
            from dolfin import cross, sqrt, dot
            from fenicsmembranes.calculus_utils import contravariant_base_vector

            # Get the contravariant tangent basis
            self.Gsup1 = contravariant_base_vector(self.Gsub1, self.Gsub2)
            self.Gsup2 = contravariant_base_vector(self.Gsub2, self.Gsub1)

            # Reference normal
            self.Gsub3 = cross(self.Gsub1, self.Gsub2)
            self.Gsup3 = self.Gsub3 / dot(self.Gsub3, self.Gsub3)

            # Construct the covariant convective basis
            self.gsub1 = self.Gsub1 + self.u.dx(0)
            self.gsub2 = self.Gsub2 + self.u.dx(1)

            # Construct the contravariant convective basis
            self.gsup1 = contravariant_base_vector(self.gsub1, self.gsub2)
            self.gsup2 = contravariant_base_vector(self.gsub2, self.gsub1)

            # Deformed normal
            self.gsub3 = cross(self.gsub1, self.gsub2)
            self.gsup3 = self.gsub3 / dot(self.gsub3, self.gsub3)

            # Deformation gradient
            gradu = outer(self.u.dx(0), self.Gsup1) + outer(
                self.u.dx(1), self.Gsup2)
            I = Identity(self.nsd)

            self.F = I + gradu
            self.C = self.F.T * self.F  # from initial to current

            # 3x2 deformation tensors
            # TODO: check/test
            self.F_0 = as_tensor([self.Gsub1, self.Gsub2]).T
            self.F_n = as_tensor([self.gsub1, self.gsub2]).T

            # 2x2 surface metrics
            self.C_0 = self.get_metric(self.Gsub1, self.Gsub2)
            self.C_0_sup = self.get_metric(self.Gsup1, self.Gsup2)
            self.C_n = self.get_metric(self.gsub1, self.gsub2)

            # TODO: not tested. do we need these?
            self.det_C_0 = dot(self.Gsub1, self.Gsub1) * dot(
                self.Gsub2, self.Gsub2) - dot(self.Gsub1, self.Gsub2)**2
            self.det_C_n = dot(self.gsub1, self.gsub1) * dot(
                self.gsub2, self.gsub2) - dot(self.gsub1, self.gsub2)**2

            self.lambda1, self.lambda2, self.lambda3 = self.get_lambdas()

            self.I1 = inner(inv(self.C_0), self.C_n)
            self.I2 = det(self.C_n) / det(self.C_0)

        else:
            raise Exception("Could not infer spatial dimension")

        # Unit normals
        self.J_A = sqrt(dot(self.Gsub3, self.Gsub3))
        self.N = self.Gsub3 / self.J_A
        self.j_a = sqrt(dot(self.gsub3, self.gsub3))
        self.n = self.gsub3 / self.j_a
Пример #27
0
def calcs(fname):
    data = pickle.load(open(fname+'.pickle'))
    mesh = dolfin.Mesh(data['meshfile'])
    elen = np.array([e.length() for e in dolfin.edges(mesh)])
    ave_elen = np.average(elen)
    material_meshfn = dolfin.MeshFunction('uint', mesh, data['materialsfile'])
    V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", data['order'])
    x = data['x']
    x_r = as_dolfin_vector(x.real)
    x_i = as_dolfin_vector(x.imag)
    E_r = dolfin.Function(V, x_r)
    E_i = dolfin.Function(V, x_i)
    k0 = 2*np.pi*data['freq']/c0

    n = V.cell().n

    ReS = (1/k0/Z0)*dolfin.dot(n, (dolfin.cross(E_r, -dolfin.curl(E_i)) +
                                   dolfin.cross(E_i, dolfin.curl(E_r))))*dolfin.ds
    energy_flux = dolfin.assemble(ReS)
    surface_flux = SurfaceFlux(V)
    surface_flux.set_dofs(x)
    surface_flux.set_k0(k0)
    energy_flux2 = surface_flux.calc_flux()
    assert(np.allclose(energy_flux, energy_flux2, rtol=1e-8, atol=1e-8))    

    def boundary(x, on_boundary):
        return on_boundary
    E_r_dirich = dolfin.DirichletBC(V, E_r, boundary)
    x_r_dirich = as_dolfin_vector(np.zeros(len(x)))
    E_r_dirich.apply(x_r_dirich)
    E_i_dirich = dolfin.DirichletBC(V, E_i, boundary)
    x_i_dirich = as_dolfin_vector(np.zeros(len(x)))
    E_i_dirich.apply(x_i_dirich)
    x_dirich = x_r_dirich.array() + 1j*x_i_dirich.array()

    emfunc = CalcEMFunctional(V)
    emfunc.set_k0(k0)
    cell_domains = dolfin.CellFunction('uint', mesh)
    cell_domains.set_all(0)
    cell_region = 1
    boundary_cells = Geometry.BoundaryEdgeCells(mesh)
    boundary_cells.mark(cell_domains, cell_region)
    emfunc.set_cell_domains(cell_domains, cell_region)

    emfunc.set_E_dofs(x)
    emfunc.set_g_dofs(1j*x_dirich.conjugate()/k0/Z0)
    var_energy_flux = emfunc.calc_functional().conjugate()
    var_surf_flux = VariationalSurfaceFlux(V)
    var_surf_flux.set_dofs(x)
    var_surf_flux.set_k0(k0)
    var_energy_flux2 = var_surf_flux.calc_flux()
    assert(np.allclose(var_energy_flux, var_energy_flux2, rtol=1e-8, atol=1e-8))

    complex_voltage = ComplexVoltageAlongLine(V)
    complex_voltage.set_dofs(x)

    volts = complex_voltage.calculate_voltage(*data['source_endpoints'])

    result = dict(h=ave_elen, order=order, volts=volts,
                  sflux=energy_flux, vflux=var_energy_flux)


    print 'source power: ', volts*data['I']
    print 'energy flux:      ', energy_flux
    print 'var energy flux: ', var_energy_flux

    # print '|'.join(str(s) for s in ('', volts*data['I'], energy_flux,
    #                                 var_energy_flux, ''))

    return result
def s_number(m, dx):
    s_density = df.dot(m, df.cross(df.Dx(m, 0), df.Dx(m, 1)))
    return 1/(4*np.pi) * df.assemble(s_density*dx)
             + time_step * c[0] * equation_coefficients[1] * a_operator(dv, del_v) \
             - time_step * b_operator(del_v, dp) \
             - time_step * b_operator(dv, del_p)
rhs_momentum = a[1] * dot(v0, del_v) * dV \
             - a[2] * dot(v00, del_v) * dV \
             - time_step * b[1] * c_operator(v0, v0, del_v) \
             + time_step * b[2] * c_operator(v00, v00, del_v) \
             + time_step * equation_coefficients[2] * extrapolated_temperature * dot(gravity_vector, del_v) * dV
if rotation == True:
    print "\nAdding rotation to the model...\n"
    if space_dim == 2:
        rhs_momentum += - time_step * equation_coefficients[0] * dot(cross_2D(extrapolated_velocity), del_v) * dV
    elif space_dim == 3:
        rotation_vector = dlfn.Constant((0., 0., 1.))
        rhs_momentum += - time_step * equation_coefficients[0] * dot(
                            dlfn.cross(rotation_vector, extrapolated_velocity),
                            del_v) * dV
# energy equation
lhs_energy = a[0] * dot(dT, del_T) * dV \
           + time_step * equation_coefficients[3] * a_operator(dT, del_T)
rhs_energy = a[1] * dot(T0, del_T) * dV \
           - a[2] * dot(T00, del_T) * dV \
           - time_step * b[1] * c_operator(v0, T0, del_T) \
           + time_step * b[2] * c_operator(v00, T00, del_T)
lhs = lhs_momentum + lhs_energy
#===============================================================================
# full problem
lhs = lhs_momentum + lhs_energy
rhs = rhs_momentum + rhs_energy
if not use_assembler_method:
    # linear problem
Пример #30
0
This should be replaced in the parts of the code where dmdt is computed.
"""
import dolfin as df
import time

mesh = df.IntervalMesh(1000, 0, 1)
S3 = df.VectorFunctionSpace(mesh, 'CG', 1, 3)

a = df.Function(S3)
b = df.Function(S3)
a.assign(df.Constant((1, 0, 0)))  # unit x vector
b.assign(df.Constant((0, 1, 0)))  # unit y vector

alpha = 01
gamma = 2.11e5
m = df.Function(S3)
m.assign(df.Constant((0, 0, 1)))
Heff = df.Function(S3)
Heff.assign(df.Constant((0, 0.3, 0.2)))
dmdt = df.Function(S3)

start = time.time()
for i in range(1000):
    L = df.dot(
        -gamma / (1 + alpha * alpha) * df.cross(m, Heff) - alpha * gamma /
        (1 + alpha * alpha) * df.cross(m, df.cross(m, Heff)),
        df.TestFunction(S3)) * df.dP
    df.assemble(L, tensor=dmdt.vector())
stop = time.time()
print 'Time:', stop - start
Пример #31
0
# define dmdt, test and trial functions
dmdt = df.Function(V)
v = df.TrialFunction(V)
w = df.TestFunction(V)

# define the exchange field
# f_ex = df.Constant(2*A/(mu0*Ms))

# results for m_x at times t_array in
mx_simulation = np.zeros(t_array.shape)

for i, t in enumerate(t_array):

    mx_simulation[i] = m((0, 0, 0))[0]

    a = df.inner(df.Constant(alpha) * v + df.cross(m, v), w) * df.dx
    L = df.inner(gamma * Heff, w) * df.dx
    df.solve(a == L, dmdt)

    m += dmdt * df.Constant(dt)
    m = df.project(m / df.sqrt(df.dot(m, m)), V)

###################
# Analytic solution
###################
mx_analytic = macrospin_analytic_solution(alpha, gamma, H, t_array)

###################
# Plot comparison.
###################
plt.figure(figsize=(8, 5))
Пример #32
0
V = df.VectorFunctionSpace(mesh, "CG", 1, dim=3)
u = df.TrialFunction(V)
v = df.TestFunction(V)

f = df.Function(V)
g = df.Function(V)
fxg = df.Function(V)

f.assign(df.Constant((1, 0, 0)))
g.assign(df.Constant((0, 1, 0)))

# FINITE ELEMENT METHOD
# but dP instead of dx (both work)

a = df.dot(u, v) * df.dP
L = df.dot(df.cross(f, g), v) * df.dP

u = df.Function(V)
start = time.time()
for _ in xrange(1000):
    df.solve(a == L, u)
stop = time.time()
print "fem, delta = {} s.".format(stop - start)
print u.vector().array()

# LINEAR ALGEBRA FORMULATION

A = df.assemble(a)
b = df.Function(V)

u = df.Function(V)