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()]
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
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i)/(self.k0*Z0) H_i = curl(self.E_r)/(self.k0*Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r*dolfin.cos(phase) - J_i*dolfin.sin(phase) N_i = J_r*dolfin.sin(phase) + J_i*dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict( r_theta=dot(theta_hat, N_r)*ds, r_phi=dot(phi_hat, N_r)*ds, i_theta=dot(theta_hat, N_i)*ds, i_phi=dot(phi_hat, N_i)*ds) return self.N_form
def _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 _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 __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
def get_N_form(self): try: return self.N_form except AttributeError: pass # Set up magnetic field and equivalent electric current forms H_r = -curl(self.E_i) / (self.k0 * Z0) H_i = curl(self.E_r) / (self.k0 * Z0) J_r = cross(self.n, H_r) J_i = cross(self.n, H_i) #------------------------------ # Set up form for far field potential N theta_hat = self.theta_hat phi_hat = self.phi_hat phase = self.phase N_r = J_r * dolfin.cos(phase) - J_i * dolfin.sin(phase) N_i = J_r * dolfin.sin(phase) + J_i * dolfin.cos(phase) # UFL does not seem to like vector valued functionals, so we split the # final functional from into theta and phi components self.N_form = dict(r_theta=dot(theta_hat, N_r) * ds, r_phi=dot(phi_hat, N_r) * ds, i_theta=dot(theta_hat, N_i) * ds, i_phi=dot(phi_hat, N_i) * ds) return self.N_form
def __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()
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)
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]))
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)
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()
# 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)
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]
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],
(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)
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
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),
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)
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))
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()
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()
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