class test_fillament_current_source(unittest.TestCase): test_data_file = 'fillament_source_test_data.pickle' rtol=1e-10 atol=1e-12 def setUp(self): desired_file = Paths.get_module_path_file(self.test_data_file, __file__) env = self.environment = FillamentEnvironment(desired_file) self.DUT = FillamentCurrentSource() self.DUT.set_function_space(env.discretisation_space) self.DUT.set_no_integration_points(env.no_integration_points) self.DUT.set_source_endpoints(env.source_endpoints) self.DUT.set_value(env.I) def test_source(self): actual_dofnos, actual_rhs = self.DUT.get_contribution() sortind = np.argsort(actual_dofnos) actual_dofnos = actual_dofnos[sortind].copy() actual_rhs = actual_rhs[sortind].copy() self.assertTrue(np.all(actual_dofnos == self.environment.desired_dofnos)) self.assertTrue(np.allclose(actual_rhs, self.environment.desired_rhs_contribs, rtol=self.rtol, atol=self.atol)) def test_negative_direction(self): dofnos, rhs = self.DUT.get_contribution() sortind = np.argsort(dofnos) dofnos = dofnos[sortind] rhs = rhs[sortind] self.DUT.set_source_endpoints(-self.DUT.source_endpoints) dofnos_neg, rhs_neg = self.DUT.get_contribution() sortind = np.argsort(dofnos_neg) dofnos_neg = dofnos_neg[sortind] rhs_neg = rhs_neg[sortind] self.assertTrue(np.all(dofnos == dofnos_neg)) self.assertTrue(np.allclose(rhs, -rhs_neg))
def get_current_source(self): """get FillamentCurrentSource instance Each call results in a new instance being instantiated. """ cs = FillamentCurrentSource() cs.set_function_space(self.function_space) cs.set_source_endpoints(self.source_parameters['endpoints']) cs.set_value(self.source_parameters['I']) return cs
def test_ff_error(self): sucemfem.Utilities.Optimization.set_dolfin_optimisation(True) ### Postprocessing requests theta_deg = N.linspace(10, 170, 161) no_ff_pts = len(theta_deg) phi_deg = N.zeros(no_ff_pts) ### Problem parameters freq = 1.0e+9 # Frequency lam = c0/freq l = lam/4 # Dipole length I = 1.0 # Dipole current source_direction_z = N.array([0,0,1.]) # Source orientation source_direction_x = N.array([1.,0,0]) # Source orientation source_direction_y = N.array([0,1,0.]) # Source orientation source_centre = N.array([0,0,0.]) # Position of the source source_endpoints_z = N.array( [-source_direction_z*l/2, source_direction_z*l/2]) + source_centre source_endpoints_x = N.array( [-source_direction_x*l/2, source_direction_x*l/2]) + source_centre source_endpoints_y = N.array( [-source_direction_y*l/2, source_direction_y*l/2]) + source_centre ### Discretisation settings order = 2 domain_size = N.array([lam]*3)*1 max_edge_len = lam/6 mesh = get_centred_cube(domain_size, max_edge_len) ### Implementation # ## Set up materials function with all free-space material_mesh_func = dolfin.MeshFunction('uint', mesh, 3) material_mesh_func.set_all(0) materials = {0:dict(eps_r=1, mu_r=1),} ## Set up 1st-order analytical ABC abc = ABCBoundaryCondition() abc.set_region_number(1) bcs = BoundaryConditions() bcs.add_boundary_condition(abc) ## Set up high level problem class dp = DrivenProblemABC() dp.set_mesh(mesh) dp.set_basis_order(order) dp.set_material_regions(materials) dp.set_region_meshfunction(material_mesh_func) dp.set_boundary_conditions(bcs) ## Set up current fillament source current_sources = sucemfem.Sources.current_source.CurrentSources() fillament_source = FillamentCurrentSource() fillament_source.no_integration_points = 1000 fillament_source.set_source_endpoints(source_endpoints_z) fillament_source.set_value(I) current_sources.add_source(fillament_source) ## Set source in problem container dp.set_sources(current_sources) dp.init_problem() dp.set_frequency(freq) ## Get sytem LHS matrix and RHS Vector A = dp.get_LHS_matrix() b_z = dp.get_RHS() fillament_source.set_source_endpoints(source_endpoints_x) b_x = dp.get_RHS() fillament_source.set_source_endpoints(source_endpoints_y) b_y = dp.get_RHS() #import pdb ; pdb.set_trace() A print 'solve using UMFPack' umf_solver = sucemfem.Utilities.LinalgSolvers.UMFPACKSolver(A) x_z = umf_solver.solve(b_z) x_x = umf_solver.solve(b_x) x_y = umf_solver.solve(b_y) ## Post-process solution to obtain far-field print 'calculating far field' surf_ntff = surface_ntff.NTFF(dp.function_space) surf_ntff.set_dofs(x_z) surf_ntff.set_frequency(freq) surf_E_ff_z = N.array([surf_ntff.calc_pt(th_deg, ph_deg) for th_deg, ph_deg in zip(theta_deg, phi_deg)]) surf_E_theta_z = surf_E_ff_z[:,0] surf_E_phi_z = surf_E_ff_z[:,1] surf_ntff.set_dofs(x_x) surf_E_ff_x = N.array([surf_ntff.calc_pt(th_deg+90, ph_deg) for th_deg, ph_deg in zip(theta_deg, phi_deg)]) surf_E_theta_x = surf_E_ff_x[:,0] surf_E_phi_x = surf_E_ff_x[:,1] surf_ntff.set_dofs(x_y) surf_E_ff_y = N.array([surf_ntff.calc_pt(th_deg+90, ph_deg) for th_deg, ph_deg in zip(theta_deg, phi_deg)]) surf_E_theta_y = surf_E_ff_y[:,0] surf_E_phi_y = surf_E_ff_y[:,1] ## Calculate some errors relative to the analytical solution an_E_theta = [current_fillament_farfield.eval_E_theta(freq, l, I, th) for th in N.deg2rad(theta_deg)] err_z = normalised_RMS( surf_E_theta_z, an_E_theta, surf_E_phi_z) err_theta_z = normalised_RMS(surf_E_theta_z, an_E_theta) err_abs_theta_z = normalised_RMS(N.abs(surf_E_theta_z), N.abs(an_E_theta)) err_x = normalised_RMS( surf_E_theta_x, an_E_theta, surf_E_phi_x) err_theta_x = normalised_RMS(surf_E_theta_x, an_E_theta) err_abs_theta_x = normalised_RMS(N.abs(surf_E_theta_x), N.abs(an_E_theta)) err_y = normalised_RMS( surf_E_theta_y, an_E_theta, surf_E_phi_y) err_theta_y = normalised_RMS(surf_E_theta_y, an_E_theta) err_abs_theta_y = normalised_RMS(N.abs(surf_E_theta_y), N.abs(an_E_theta)) print 'Far-field RMS error: ', err_z, err_x, err_y # Expected error for lam/6 mesh, 2nd order discretisation, # lam/4 current fillament source is ~4.685% self.assertTrue(err_z < 4.7) self.assertTrue(err_x < 4.7) self.assertTrue(err_z < 4.7)
## Set up 1st-order analytical ABC abc = ABCBoundaryCondition() abc.set_region_number(1) bcs = BoundaryConditions() bcs.add_boundary_condition(abc) ## Set up high level problem class dp = DrivenProblemABC() dp.set_mesh(mesh) dp.set_basis_order(order) dp.set_material_regions(materials) dp.set_region_meshfunction(material_mesh_func) dp.set_boundary_conditions(bcs) ## Set up current fillament source current_sources = sucemfem.Sources.current_source.CurrentSources() fillament_source = FillamentCurrentSource() fillament_source.set_source_endpoints(source_endpoints) fillament_source.set_value(I) current_sources.add_source(fillament_source) ## Set source in problem container dp.set_sources(current_sources) dp.init_problem() dp.set_frequency(freq) ## Get sytem LHS matrix and RHS Vector A = dp.get_LHS_matrix() b = dp.get_RHS() ## Solve. Choose spare solver if UMFPack runsout of memory # print 'solve using scipy bicgstab' # x = solve_sparse_system ( A, b, preconditioner_type='diagonal') print 'solve using UMFPack' umf_solver = sucemfem.Utilities.LinalgSolvers.UMFPACKSolver(A)
abc = ABCBoundaryCondition() abc.set_region_number(1) bcs = BoundaryConditions() bcs.add_boundary_condition(abc) ## Set up high level problem class dp = DrivenProblemABC() dp.set_mesh(mesh) dp.set_basis_order(order) dp.set_material_regions(materials) dp.set_region_meshfunction(material_mesh_func) dp.set_boundary_conditions(bcs) ## Set up current fillament source current_sources = sucemfem.Sources.current_source.CurrentSources() fillament_source = FillamentCurrentSource() fillament_source.no_integration_points = 1000 fillament_source.set_source_endpoints(source_endpoints_z) fillament_source.set_value(I) current_sources.add_source(fillament_source) ## Set source in problem container dp.set_sources(current_sources) dp.init_problem() dp.set_frequency(freq) ## Get sytem LHS matrix and RHS Vector A = dp.get_LHS_matrix() b_z = dp.get_RHS() #import pdb ; pdb.set_trace() A print 'solve using UMFPack' umf_solver = sucemfem.Utilities.LinalgSolvers.UMFPACKSolver(A)
l = lam/4 # Dipole length # l = 2.3*lam # Dipole length I = 1.0 # Dipole current source_direction = np.array([0,0,1.]) # Source orientation source_centre = np.array([0,0,0.]) # Position of the source source_endpoints = np.array( [-source_direction*l/2, source_direction*l/2]) + source_centre ## Discretisation settings order = 2 domain_size = np.array([lam]*3)/2 max_edge_len = lam/3 mesh = get_centred_cube(domain_size, max_edge_len) ## Implementation V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", order) dipole_source = FillamentCurrentSource() dipole_source.no_integration_points = 20 dipole_source.set_function_space(V) dipole_source.set_source_endpoints(source_endpoints) dipole_source.set_value(I) dofnos, rhs_contribs = dipole_source.get_contribution() sortind = np.argsort(dofnos) dofnos = dofnos[sortind].copy() rhs_contribs = rhs_contribs[sortind].copy() pickle.dump(dict(order=order,I=I, source_endpoints=source_endpoints, domain_size=domain_size, max_edge_len=max_edge_len, no_integration_points=dipole_source.no_integration_points, dofnos=dofnos, rhs_contribs=rhs_contribs), open('fillament_source_test_data.pickle', 'w'))
bcs.add_boundary_condition(abc) pec_walls = PECWallsBoundaryCondition() pec_walls.init_with_meshfunction (pec_mesh_function, PEC_label) bcs.add_boundary_condition(pec_walls) ## Set up high level problem class dp = DrivenProblemABC() dp.set_mesh(mesh) dp.set_basis_order(order) dp.set_material_regions(materials) dp.set_region_meshfunction(materials_mesh_function) dp.set_boundary_conditions(bcs) ## Set up current fillament source current_sources = sucemfem.Sources.current_source.CurrentSources() fillament_source = FillamentCurrentSource() fillament_source.set_source_endpoints(feed_pts) fillament_source.set_value(I) current_sources.add_source(fillament_source) ## Set source in problem container dp.set_sources(current_sources) print 'init problem' dp.init_problem() Zs = [] def get_solver(type, A): ## Solve. Choose sparse solver if UMFPack runsout of memory if type == 'umfpack': print 'solve using UMFPack' solver = sucemfem.Utilities.LinalgSolvers.UMFPACKSolver(A) elif type == 'bicgstab': print 'solve using scipy bicgstab'
source_direction = np.array([0, 0, 1.]) # Source orientation source_centre = np.array([0, 0, 0.]) # Position of the source source_endpoints = np.array( [-source_direction * l / 2, source_direction * l / 2]) + source_centre ## Discretisation settings order = 2 domain_size = np.array([lam] * 3) / 2 max_edge_len = lam / 3 mesh = get_centred_cube(domain_size, max_edge_len) ## Implementation V = dolfin.FunctionSpace(mesh, "Nedelec 1st kind H(curl)", order) dipole_source = FillamentCurrentSource() dipole_source.no_integration_points = 20 dipole_source.set_function_space(V) dipole_source.set_source_endpoints(source_endpoints) dipole_source.set_value(I) dofnos, rhs_contribs = dipole_source.get_contribution() sortind = np.argsort(dofnos) dofnos = dofnos[sortind].copy() rhs_contribs = rhs_contribs[sortind].copy() pickle.dump( dict(order=order, I=I, source_endpoints=source_endpoints, domain_size=domain_size, max_edge_len=max_edge_len, no_integration_points=dipole_source.no_integration_points, dofnos=dofnos, rhs_contribs=rhs_contribs),