def _generate_function_spaces(regularity, dim):
    """
    Return a list of lambda functions, that, given a mesh and a
    degree, defines a conforming finite element spaces for the given
    space name
    """
    if dim == 1:
        vFunctionSpace = FunctionSpace
    else:
        vFunctionSpace = VectorFunctionSpace

    spaces = {"h1": (lambda u, v: (dot(u,v) + inner(grad(u),grad(v)))*dx,
                     [lambda mesh, deg: vFunctionSpace(mesh, "CG", deg)]),

              "hdiv": (lambda u, v: (dot(u, v) + div(u)*div(v))*dx,
                       [lambda mesh, deg: vFunctionSpace(mesh, "CG", deg),
                        lambda mesh, deg: FunctionSpace(mesh, "RT", deg),
                        lambda mesh, deg: FunctionSpace(mesh, "BDM", deg)]),

              "hcurl": (lambda u, v: (dot(u, v) + inner(curl(u), curl(v)))*dx,
                        [lambda mesh, deg: vFunctionSpace(mesh, "CG", deg),
                         lambda mesh, deg: FunctionSpace(mesh, "N1curl", deg)]),

              "l2": (lambda p, q: dot(p, q)*dx,
                     [lambda mesh, deg: vFunctionSpace(mesh, "CG", deg),
                      lambda mesh, deg: vFunctionSpace(mesh, "DG", deg)])
              }
    return spaces[regularity.lower()]
Exemple #2
0
 def get_stiffness_form(self):
     """Get 'stiffness' / curl . curl matrix form"""
     u = self.trial_function
     v = self.test_function
     mu_r = self.material_functions['mu_r']
     s = dot(curl(v), curl(u))/mu_r*dx
     return s
Exemple #3
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
Exemple #4
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
Exemple #5
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
def Matrix_creation(mesh,mu_r,k,k0,ref,extinction = None,vector_order = 3,nodal_order = 3):
    combined_space = function_space(vector_order,nodal_order,mesh)
    # Define the test and trial functions from the combined space here N_i and N_j are Nedelec 
    # basis functions and L_i and L_j are Lagrange basis functions
    (N_i,L_i) = df.TestFunctions(combined_space)
    (N_j,L_j) = df.TrialFunctions(combined_space)
    e_r_real = epsilon_real(ref)

    s_tt_ij = 1.0/mu_r*df.inner(df.curl(N_i),df.curl(N_j))
    t_tt_ij = e_r_real*df.inner(N_i,N_j)
    s_zz_ij = (1.0/mu_r) * df.inner(df.grad(L_i),df.grad(L_j))
    t_zz_ij = e_r_real*df.inner(L_i,L_j)


    A_tt_ij = s_tt_ij - k0**2*t_tt_ij
    B_zz_ij = s_zz_ij - k0**2*t_zz_ij

    B_tt_ij = 1/mu_r*df.inner(N_i, N_j)
    B_tz_ij = 1/mu_r*df.inner(N_i, df.grad(L_j))

    B_zt_ij = 1/mu_r*df.inner(df.grad(L_i),N_j)
    #post-multiplication by dx will result in integration over the domain of the mesh at assembly time
    A_ij = A_tt_ij*df.dx
    B_ij = (B_tt_ij+B_tz_ij+B_zt_ij+B_zz_ij)*df.dx
    #assemble the system Matrices. If there is loss in the system then
    #we create a new set of matrixes and assemble them


    ####This is to try and introduce the complex part
    if k !=0:
        A = df.assemble(A_ij)
        B = df.assemble(B_ij)
        e_r_imag = epsilon_imag(extinction)
        A_ii_complex = e_r_imag*k0**2*df.inner(N_i,N_j)*df.dx
        B_ii_complex = e_r_imag*k0**2*df.inner(L_i,L_j)*df.dx
        A_complex = df.assemble(A_ii_complex)
        B_complex = df.assemble(B_ii_complex)
    else:
        A_complex, B_complex = None, None
        A,B = df.PETScMatrix(),df.PETScMatrix()
        df.assemble(A_ij, tensor=A)
        df.assemble(B_ij, tensor=B)
    return combined_space, A,B, A_complex,B_complex
    def _get_forms(self):
        if self.dirty:
            E_r, E_i, g_r, g_i = self.E_r, self.E_i, self.g_r, self.g_i
            k0 = self.k0
            eps_r = self._get_epsr_function()
            mu_r = self._get_mur_function()
            form_r = (dot(curl(E_r)/mu_r, curl(g_r)) - dot(curl(E_i)/mu_r, curl(g_i)) \
                      - k0**2*(dot(eps_r*E_r, g_r) - dot(eps_r*E_i, g_i)))*self.dx
            form_i = (dot(curl(E_r)/mu_r, curl(g_i)) + dot(curl(E_i)/mu_r, curl(g_r)) \
                  - k0**2*(dot(eps_r*E_r, g_i) + dot(eps_r*E_i, g_r)))*self.dx
            self.form_r, self.form_i = form_r, form_i
            self.dirty = False

        return self.form_r, self.form_i
    def _get_forms(self):
        if self.dirty:
            E_r, E_i, g_r, g_i = self.E_r, self.E_i, self.g_r, self.g_i
            k0 = self.k0
            eps_r = self._get_epsr_function()
            mu_r = self._get_mur_function()
            form_r = (dot(curl(E_r)/mu_r, curl(g_r)) - dot(curl(E_i)/mu_r, curl(g_i)) \
                      - k0**2*(dot(eps_r*E_r, g_r) - dot(eps_r*E_i, g_i)))*self.dx
            form_i = (dot(curl(E_r)/mu_r, curl(g_i)) + dot(curl(E_i)/mu_r, curl(g_r)) \
                  - k0**2*(dot(eps_r*E_r, g_i) + dot(eps_r*E_i, g_r)))*self.dx
            self.form_r, self.form_i = form_r, form_i
            self.dirty = False

        return self.form_r, self.form_i
    def __init__(self, u, boundary_is_streamline=False, degree=1):
        """
        Heavily based on
        https://github.com/mikaem/fenicstools/blob/master/fenicstools/Streamfunctions.py
        
        Stream function for a given general 2D velocity field.
        The boundary conditions are weakly imposed through the term
        
            inner(q, grad(psi)*n)*ds, 
        
        where grad(psi) = [-v, u] is set on all boundaries. 
        This should work for any collection of boundaries: 
        walls, inlets, outlets etc.    
        """
        Vu = u[0].function_space()
        mesh = Vu.mesh()

        # Check dimension
        if not mesh.geometry().dim() == 2:
            df.error("Stream-function can only be computed in 2D.")

        # Define the weak form
        V = df.FunctionSpace(mesh, 'CG', degree)
        q = df.TestFunction(V)
        psi = df.TrialFunction(V)
        n = df.FacetNormal(mesh)
        a = df.dot(df.grad(q), df.grad(psi)) * df.dx
        L = df.dot(q, df.curl(u)) * df.dx

        if boundary_is_streamline:
            # Strongly set psi = 0 on entire domain boundary
            self.bcs = [df.DirichletBC(V, df.Constant(0), df.DomainBoundary())]
            self.normalize = False
        else:
            self.bcs = []
            self.normalize = True
            L = L + q * (n[1] * u[0] - n[0] * u[1]) * df.ds

        # Create preconditioned iterative solver
        solver = df.PETScKrylovSolver('gmres', 'hypre_amg')
        solver.parameters['nonzero_initial_guess'] = True
        solver.parameters['relative_tolerance'] = 1e-10
        solver.parameters['absolute_tolerance'] = 1e-10

        # Store for later computation
        self.psi = df.Function(V)
        self.A = df.assemble(a)
        self.L = L
        self.mesh = mesh
        self.solver = solver
        self._triangulation = None
Exemple #10
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
Exemple #11
0
    def __setup_field_direct(self):
        dofmap = self.m.mesh_dofmap()
        S3 = df.VectorFunctionSpace(
            self.m.mesh(),
            "CG",
            1,
            dim=3,
            constrained_domain=dofmap.constrained_domain)

        u3 = df.TrialFunction(S3)
        v3 = df.TestFunction(S3)
        self.g_petsc = df.PETScMatrix()
        df.assemble(-2 * self.dmi_factor * self.D.f *
                    df.inner(v3, df.curl(u3)) * df.dx,
                    tensor=self.g_petsc)
        self.H_petsc = df.PETScVector()
Exemple #12
0
def compare_dmi_term3d_with_dolfin(Mexp):
    """Expects string to feed into df.Expression for M"""
    print "Working on Mexp=", Mexp
    Mexp = df.Expression(Mexp, degree=1)
    M = df.interpolate(Mexp, V1)
    E = dmi_term3d(M, tf, 1)[0] * df.dx
    E1 = df.assemble(E)
    E_dolfin = dmi_term3d_dolfin(M, tf, 1)[0] * df.dx
    dolfin_curl = df.project(df.curl(M), V1)
    curlx, curly, curlz = dolfin_curl.split()
    print "dolfin-curlx=", df.assemble(curlx * df.dx)
    print "dolfin-curly=", df.assemble(curly * df.dx)
    print "dolfin-curlz=", df.assemble(curlz * df.dx)
    E2 = df.assemble(E_dolfin)
    print E1, E2
    print "Diff is %.18e" % (E1 - E2)
    return abs(E1 - E2)
Exemple #13
0
 def compute(self, get):
     u = get("Velocity")
     return sqrt(assemble(curl(u)**2 * dx()))
    assign(ubar0_a, Uhbar.sub(0))
    assign(u0_a, ustar)
    assign(duh00, duh0)
    assign(duh0, project(Uh.sub(0) - ustar, W_2))

    p.increment(Udiv.cpp_object(), ustar.cpp_object(),
                np.array([1, 2], dtype=np.uintp), theta_p, step)

    if step == 2:
        theta_L.assign(theta_next)

    xdmf_u.write(Uh.sub(0), t)
    xdmf_p.write(Uh.sub(1), t)

    # Compute vorticity
    curl_func.assign(project(curl(Uh.sub(0)), W_2))
    xdmf_curl.write(curl_func, t)

timer.stop()

# Compute errors
ex = as_vector((1.0, 0.0, 0.0))
ey = as_vector((0.0, 1.0, 0.0))
ez = as_vector((0.0, 0.0, 1.0))

momentum = assemble(
    (dot(Uh.sub(0), ex) + dot(Uh.sub(0), ey) + dot(Uh.sub(0), ez)) * dx)

if comm.Get_rank() == 0:
    print("Momentum " + str(momentum))
    print("Elapsed time " + str(timer.elapsed()[0]))
Exemple #15
0
    pass


cdims = CavityDims()
cdims.a, cdims.b, cdims.c = 29, 23, 19

# Define mesh, function space
mesh = dol.UnitCube(1, 1, 1)
mesh.coordinates()[:] *= [cdims.a, cdims.b, cdims.c]
V = dol.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", 4)

# Define basis and bilinear form
u = dol.TrialFunction(V)
v = dol.TestFunction(V)
m = inner(v, u) * dx  # Mass form
s = dot(curl(v), curl(u)) * dx  # Stiffness form

# Assemble smass form
M = dol.PETScMatrix()
S = dol.PETScMatrix()
dol.assemble(m, tensor=M, mesh=mesh)
dol.assemble(s, tensor=S, mesh=mesh)

sigma = 0.03
smat = S - sigma * M
#lu = dol.LUSolver(S - sigma*M)
lu = dol.LUSolver(smat)
lu.parameters["reuse_factorization"] = True
lu.parameters["report"] = False
bb = dol.Vector(M.size(0))
xx = dol.Vector(M.size(0))
dV = dlfn.Measure("dx", mesh, subdomain_data=cellMeshFun)
normal = dlfn.FacetNormal(mesh)
#------------------------------------------------------------------------------#
# solution functions
#------------------------------------------------------------------------------#
sol = dlfn.Function(Wh)
sol0 = dlfn.Function(Wh)
sol_A = sol.sub(0)
sol_A0 = sol0.sub(0)
#------------------------------------------------------------------------------#
# weak forms and assembly
#------------------------------------------------------------------------------#
# linear forms in interior domain
from dolfin import curl, inner, dot, grad
a =   dlfn.Constant(1. / dt) * dot(A, B) * dV(intId) \
    + dlfn.Constant(0.5 * eta) * inner(curl(A), curl(B)) * dV(intId) \
    + inner(curl(A), curl(B)) * dV(extId) \
    + dot(A, grad(psi)) * dV \
    + dot(grad(phi), B) * dV
l =   dlfn.Constant(1. / dt) * dot(sol_A0, B) * dV(intId) \
    - dlfn.Constant(0.5 * eta) * inner(curl(sol_A0), curl(B)) * dV(intId)
# boundary condition
bcA = dlfn.DirichletBC(Wh.sub(0), dlfn.Constant((0.0, 0.0, 0.0)), facetMeshFun,
                       bndryId)
#------------------------------------------------------------------------------#
# linear solver
#------------------------------------------------------------------------------#
problem = dlfn.LinearVariationalProblem(a, l, sol, bcs=bcA)
solver = dlfn.LinearVariationalSolver(problem)

#vector_element = dolfin.VectorElement("Nedelec 1st kind H(curl)", mesh.ufl_cell(), vector_order)
nodal_space = dolfin.FunctionSpace(mesh, 'Lagrange', nodal_order)
#nodal_element = dolfin.FiniteElement("Lagrange", mesh.ufl_cell(), nodal_order)
#combined_space = vector_space * nodal_space
combined_space = dolfin.FunctionSpace(
    mesh,
    vector_space.ufl_element() * nodal_space.ufl_element())
#combined_element=dolfin.MixedElement([vector_element, nodal_element])
#combined_space=dolfin.FunctionSpace(mesh, combined_element)
#combined_space=dolfin.FunctionSpace(mesh, dolfin.MixedElement([vector_element, nodal_element]))
(N_i, L_i) = dolfin.TestFunctions(combined_space)
(N_j, L_j) = dolfin.TrialFunctions(combined_space)
er = 1.
ur = 1.

s_tt_ij = 1. / ur * dolfin.inner(dolfin.curl(N_i), dolfin.curl(N_j))
t_tt_ij = er * dolfin.inner(N_i, N_j)
s_zz_ij = 1. / ur * dolfin.inner(dolfin.grad(L_i), dolfin.grad(L_j))
t_zz_ij = er * L_i * L_j
s_ij = (s_tt_ij + s_zz_ij) * dolfin.dx
t_ij = (t_tt_ij + t_zz_ij) * dolfin.dx
S = dolfin.assemble(s_ij)
T = dolfin.assemble(t_ij)
print("starting the boundary conditions")
markers = dolfin.MeshFunction('size_t', mesh, 1)

markers.set_all(0)
dolfin.DomainBoundary().mark(markers, 1)
electric_wall = dolfin.DirichletBC(combined_space,
                                   dolfin.Constant((0.0, 0.0, 0.0, 0.0)),
                                   markers, 1)
Exemple #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
    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()
Exemple #19
0
# Define mesh
mesh = dol.UnitCube(11,11,11)

# 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)
Exemple #20
0
psi = dlfn.TestFunction(extH1)
# measures and normal vectors
dA, dV, normals = dict(), dict(), dict()
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]
Exemple #21
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
    normals[i] = dlfn.FacetNormal(subMeshes[i])
intV = dlfn.assemble(dlfn.Constant(1.0) * dV[intId])
extV = dlfn.assemble(dlfn.Constant(1.0) * dV[extId])
#------------------------------------------------------------------------------#
# solution functions
#------------------------------------------------------------------------------#
sol_A = dlfn.Function(intHCurl)
sol_A0 = dlfn.Function(intHCurl)
sol_phi = dlfn.Function(extH1)
#------------------------------------------------------------------------------#
# weak forms and assembly in interior
#------------------------------------------------------------------------------#
# linear forms in interior domain
from dolfin import curl, inner, dot, grad
id_int = dlfn.Constant(1. / dt) * dot(A, B) * dV[intId]
a_int = dlfn.Constant(0.5 * eta) * inner(curl(A), curl(B)) * dV[intId]
b_int = u * dot(normals[intId], curl(B)) * dA[intId](intrfcId)
l_int = dlfn.Constant(1. / dt) * dot(sol_A0, B) * dV[intId] \
        - dlfn.Constant(0.5 * eta) * inner(curl(sol_A0), curl(B)) * dV[intId]
# assemble (0,0)-block
matA = dlfn.assemble(a_int)
matM = dlfn.assemble(id_int)
# assemble (0,1)-block
matB = dlfn.assemble(b_int)
#------------------------------------------------------------------------------#
# weak forms and assembly in exterior
#------------------------------------------------------------------------------#
# linear forms in exterior domain
a_ext = inner(dlfn.Constant(eta) * grad(phi), grad(psi)) * dV[extId]
# apply boundary condition
bc = dlfn.DirichletBC(extH1, dlfn.Constant(0.), facetSubMeshFuns[extId],
Exemple #23
0
(N_j, ) = dolfin.TrialFunctions(vector_space)

print('made functions')
er = 1.
ur = 1.

ermarkers = dolfin.MeshFunction('double', mesh, 3)
vals = np.zeros(mesh.num_cells())
for material in dmesh.cell_physical.keys():
    for cell_tag in dmesh.cell_physical[material].keys():
        vals[dmesh.cellmap_inv[cell_tag]] = er_dict[material]
ermarkers.set_values(vals)

er = Expression(ermarkers)

s_ij = 1. / ur * dolfin.inner(dolfin.curl(N_i), dolfin.curl(N_j)) * dolfin.dx
t_ij = er * dolfin.inner(N_i, N_j) * dolfin.dx

S = dolfin.PETScMatrix()
T = dolfin.PETScMatrix()
print('before assemble: {:}s'.format(time.time() - t_ini))
dolfin.assemble(s_ij, tensor=S)
print('first assembly')
dolfin.assemble(t_ij, tensor=T)

#%%

print("starting the boundary conditions")
t_ini = time.time()
markers = dolfin.MeshFunction('size_t', mesh, 2)
vals = np.zeros(markers.array().shape, dtype=int)
Exemple #24
0
Vh = dlfn.FunctionSpace(mesh, P1Curl * P1)
# rhs function
jumpM = dlfn.Constant((0.0, 0.0, -1.0))
# trial functions
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")
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
Exemple #26
0
                              for j in range(N_tot)])))



#=================Finite Element solutions==================




mesh=dolfin.RectangleMesh(dolfin.Point(0,0), dolfin.Point(np.pi,np.pi),N,N)

V = dolfin.FunctionSpace(mesh, "Lagrange", 1)
v = dolfin.TestFunction(V)
u = dolfin.TrialFunction(V)

s = dolfin.inner(dolfin.curl(v), dolfin.curl(u))*dolfin.dx
t = dolfin.inner(v, u)*dolfin.dx

S = dolfin.PETScMatrix()
T = dolfin.PETScMatrix()

dolfin.assemble(s, tensor=S)
dolfin.assemble(t, tensor=T)
print(S.size(1))

markers=dolfin.MeshFunction('size_t',mesh,1)
markers.set_all(0)
dolfin.DomainBoundary().mark(markers,1)

electric_wall = dolfin.DirichletBC(V, 
                                   dolfin.Constant(0.0),
Exemple #27
0
material_func_space = dol.FunctionSpace(mesh, 'DG', 0)
eps = dol.Function(material_func_space)
eps.vector()[:] = N.array([eps_vals[int(i)] for i in material_mesh_func.array()])


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

# Define basis and bilinear form
u = dol.TrialFunction(V)
v = dol.TestFunction(V)

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

def boundary(x, on_boundary):
    return on_boundary
zero = dol.Expression(("0.0", "0.0", "0.0"), degree=1)
bc = dol.DirichletBC(V, zero, boundary)



# Assemble smass form
M = dol.PETScMatrix()
S = dol.PETScMatrix()
dol.assemble(m, tensor=M, mesh=mesh)
bc.apply(M)
dol.assemble(s, tensor=S, mesh=mesh)
Exemple #28
0
 def as_real_imag(self, deep=True, **hints):
     u_re, u_im = self.args[0].as_real_imag()
     return (curl(u_re), curl(u_im))
Exemple #29
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()
Exemple #30
0
for kp,p in enumerate(pp):
    for kn,n in enumerate(n_elements):
        print 'p = ' + str(p) + '   k = ' + str(n)
        mesh = dolfin.RectangleMesh(dolfin.Point(xBounds[0],yBounds[0],0.0),dolfin.Point(xBounds[1],yBounds[1],0.0),n,n,'crossed')

        # define the function spaces
        U = dolfin.FunctionSpace(mesh,'RT',p)      # velocity
        PSI = dolfin.FunctionSpace(mesh,'CG',p)    # stream function
        P = dolfin.FunctionSpace(mesh,'DG',p-1)    # divergence of velocity


        # compute the finite element approximation of the analytical stream function
        psi_h = project(psi_exact,PSI)

        # compute the velocity 
        u_h = project(dolfin.curl(psi_h), U)

        # compute the divergence 
        p_h = project(dolfin.div(u_h),P )


        # get the maximum value of the divergence
        div_max[kp,kn] = numpy.abs(p_h.vector().array()).max()

print div_max

pylab.semilogy(pp,div_max)
pylab.legend(n_elements,loc=4)
pylab.xlabel('p')
pylab.show()
Exemple #31
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