コード例 #1
0
class NTFF(object):
    def __init__(self, function_space, testing_space=None):
        self.function_space = function_space
        if testing_space is None:
            testing_space = function_space
        self.testing_space = testing_space
        self.functional = CalcEMFunctional(function_space, testing_space)
        self.testing_interpolator = SurfaceInterpolant(testing_space)
        self.cell_domains = dolfin.CellFunction('uint',
                                                self.function_space.mesh())
        self.cell_domains.set_all(0)
        self.cell_region = 1
        boundary_cells = Geometry.BoundaryEdgeCells(self.function_space.mesh())
        boundary_cells.mark(self.cell_domains, self.cell_region)
        self.surface_forms = SurfaceNTFFForms(self.function_space)
        self.testing_expression_gen = TransformTestingExpression()
        self.functional.set_cell_domains(self.cell_domains, self.cell_region)

    def set_k0(self, k0):
        self.k0 = k0
        self.functional.set_k0(k0)

    def set_frequency(self, frequency):
        self.frequency = frequency
        self.set_k0(self.frequency * 2 * np.pi / c0)

    def set_dofs(self, dofs):
        self.functional.set_E_dofs(dofs)
        self.surface_forms.set_dofs(dofs)

    def calc_pt(self, theta_deg, phi_deg):
        # H-field contribution using variational calculation
        E_H_theta, E_H_phi = self.calc_pt_E_H(theta_deg, phi_deg)
        theta = np.deg2rad(theta_deg)
        phi = np.deg2rad(phi_deg)
        self.surface_forms.set_parms(theta, phi, self.k0)
        L_theta, L_phi = self.surface_forms.assemble_L()
        #------------------------------
        # Calculate the far fields normalised to radius 1.
        r_fac = 1j * self.k0 * np.exp(-1j * self.k0) / (4 * np.pi)
        E_theta = r_fac * (-L_phi + E_H_theta)
        E_phi = r_fac * (L_theta + E_H_phi)
        return (E_theta, E_phi)

    def calc_pt_E_H(self, theta_deg, phi_deg):
        theta = np.deg2rad(theta_deg)
        phi = np.deg2rad(phi_deg)
        rhat = np.array([
            np.sin(theta) * np.cos(phi),
            np.sin(theta) * np.sin(phi),
            np.cos(theta)
        ],
                        dtype=np.float64)
        theta_hat = np.array([
            np.cos(theta) * np.cos(phi),
            np.cos(theta) * np.sin(phi), -np.sin(theta)
        ],
                             dtype=np.float64)
        phi_hat = np.array([-np.sin(phi), np.cos(phi), 0.], dtype=np.float64)
        E_H_theta = self.calc_ff_func(rhat, theta_hat)
        E_H_phi = self.calc_ff_func(rhat, phi_hat)
        return E_H_theta, E_H_phi

    def calc_ff_func(self, rhat, ahat):
        self.testing_expression_gen.set_parms(rhat, ahat, self.k0)
        fit_expr_r, fit_expr_i = self.testing_expression_gen.get_expression()
        self.testing_interpolator.set_interpolant_expression(
            fit_expr_r, fit_expr_i)
        g_dofs = self.testing_interpolator.calculate_interpolation()
        self.functional.set_g_dofs(g_dofs)
        return self.functional.calc_functional()
コード例 #2
0
ファイル: power_flux.py プロジェクト: sunhangqi/sucem-fem
class VariationalSurfaceFlux(object):
    def __init__(self, function_space):
        self.function_space = V = function_space
        self.E_r = dolfin.Function(V)
        self.E_i = dolfin.Function(V)
        self.mur_function = None
        self.epsr_function = None
        ## Set CalcEMCalcEMFunctional to only integrate along a skin
        ## of elements connected to the boundary
        boundary_cells = Geometry.BoundaryEdgeCells(V.mesh())
        cell_domains = dolfin.CellFunction('uint', V.mesh())
        cell_domains.set_all(0)
        cell_region = 1
        boundary_cells.mark(cell_domains, cell_region)
        self.functional = CalcEMFunctional(V)
        self.functional.set_cell_domains(cell_domains, cell_region)
        self.k0_dirty = True

    def set_dofs(self, dofs):
        x_r = np.real(dofs).copy()
        x_i = np.imag(dofs).copy()
        self.E_r.vector()[:] = x_r
        self.E_i.vector()[:] = x_i
        self.dofs = dofs

        boundary = dolfin.DomainBoundary()
        E_r_dirich = dolfin.DirichletBC(self.function_space, self.E_r,
                                        boundary)
        E_i_dirich = dolfin.DirichletBC(self.function_space, self.E_i,
                                        boundary)
        x_r_dirich = as_dolfin_vector(np.zeros(len(x_r)))
        x_i_dirich = as_dolfin_vector(np.zeros(len(x_r)))
        E_r_dirich.apply(x_r_dirich)
        E_i_dirich.apply(x_i_dirich)
        self.dirich_dofs = x_r_dirich.array() + 1j * x_i_dirich.array()
        self.functional.set_E_dofs(dofs)

    def set_k0(self, k0):
        self.k0 = k0
        self.functional.set_k0(k0)
        self.k0_dirty = True

    def set_epsr_function(self, epsr_function):
        self.epsr_function = epsr_function
        self.functional.set_epsr_function(epsr_function)

    def set_mur_function(self, mur_function):
        self.mur_function = mur_function
        self.functional.set_mur_function(mur_function)

    def calc_flux(self):
        if self.k0_dirty:
            self.functional.set_g_dofs(1j * self.dirich_dofs.conjugate() /
                                       self.k0 / Z0)
            self.k0_dirty = False
        return self.functional.calc_functional().conjugate()

    def _get_mur_function(self):
        if self.epsr_function is not None:
            mur_func = self.mur_function
        else:
            mur_func = dolfin.Constant(1)

        return mur_func

    def _get_epsr_function(self):
        if self.epsr_function is not None:
            epsr_func = self.epsr_function
        else:
            epsr_func = dolfin.Constant(1)

        return epsr_func
コード例 #3
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
コード例 #4
0
ファイル: power_flux.py プロジェクト: braamotto/sucem-fem
class VariationalSurfaceFlux(object):
    def __init__(self, function_space):
        self.function_space = V = function_space
        self.E_r = dolfin.Function(V)
        self.E_i = dolfin.Function(V)
        self.mur_function = None
        self.epsr_function = None
        ## Set CalcEMCalcEMFunctional to only integrate along a skin
        ## of elements connected to the boundary
        boundary_cells = Geometry.BoundaryEdgeCells(V.mesh())
        cell_domains = dolfin.CellFunction('uint', V.mesh())
        cell_domains.set_all(0)
        cell_region = 1
        boundary_cells.mark(cell_domains, cell_region)
        self.functional = CalcEMFunctional(V)
        self.functional.set_cell_domains(cell_domains, cell_region)
        self.k0_dirty = True

    def set_dofs(self, dofs):
        x_r = np.real(dofs).copy()
        x_i = np.imag(dofs).copy()
        self.E_r.vector()[:] = x_r
        self.E_i.vector()[:] = x_i
        self.dofs = dofs
        
        boundary = dolfin.DomainBoundary()
        E_r_dirich = dolfin.DirichletBC(
            self.function_space, self.E_r, boundary)
        E_i_dirich = dolfin.DirichletBC(
            self.function_space, self.E_i, boundary)
        x_r_dirich = as_dolfin_vector(np.zeros(len(x_r)))
        x_i_dirich = as_dolfin_vector(np.zeros(len(x_r)))
        E_r_dirich.apply(x_r_dirich)
        E_i_dirich.apply(x_i_dirich)
        self.dirich_dofs = x_r_dirich.array() + 1j*x_i_dirich.array()
        self.functional.set_E_dofs(dofs)
        
    def set_k0(self,k0):
        self.k0 = k0
        self.functional.set_k0(k0)
        self.k0_dirty = True
        
    def set_epsr_function(self, epsr_function):
        self.epsr_function = epsr_function
        self.functional.set_epsr_function(epsr_function)


    def set_mur_function(self, mur_function):
        self.mur_function = mur_function
        self.functional.set_mur_function(mur_function)

    def calc_flux(self):
        if self.k0_dirty:
            self.functional.set_g_dofs(1j*self.dirich_dofs.conjugate()/self.k0/Z0)
            self.k0_dirty = False
        return self.functional.calc_functional().conjugate()

    def _get_mur_function(self):
        if self.epsr_function is not None:
            mur_func = self.mur_function
        else:
            mur_func = dolfin.Constant(1)

        return mur_func

    def _get_epsr_function(self):
        if self.epsr_function is not None:
            epsr_func = self.epsr_function
        else:
            epsr_func = dolfin.Constant(1)

        return epsr_func
コード例 #5
0
class NTFF(object):
    def __init__(self, function_space, testing_space=None):
        self.function_space = function_space
        if testing_space is None: 
            testing_space = function_space 
        self.testing_space = testing_space 
        self.functional = CalcEMFunctional(function_space, testing_space)
        self.testing_interpolator = SurfaceInterpolant(testing_space)
        self.cell_domains = dolfin.CellFunction('uint', self.function_space.mesh())
        self.cell_domains.set_all(0)
        self.cell_region = 1
        boundary_cells = Geometry.BoundaryEdgeCells(self.function_space.mesh())
        boundary_cells.mark(self.cell_domains, self.cell_region)
        self.surface_forms = SurfaceNTFFForms(self.function_space)
        self.testing_expression_gen = TransformTestingExpression()
        self.functional.set_cell_domains(self.cell_domains, self.cell_region)

    def set_k0(self, k0):
        self.k0 = k0
        self.functional.set_k0(k0)

    def set_frequency(self, frequency):
        self.frequency = frequency
        self.set_k0(self.frequency*2*np.pi/c0)

    def set_dofs(self, dofs):
        self.functional.set_E_dofs(dofs)
        self.surface_forms.set_dofs(dofs)

    def calc_pt(self, theta_deg, phi_deg):
        # H-field contribution using variational calculation
        E_H_theta, E_H_phi = self.calc_pt_E_H(theta_deg, phi_deg)
        theta = np.deg2rad(theta_deg)
        phi = np.deg2rad(phi_deg)
        self.surface_forms.set_parms(theta, phi, self.k0)
        L_theta, L_phi = self.surface_forms.assemble_L()
        #------------------------------
        # Calculate the far fields normalised to radius 1.
        r_fac = 1j*self.k0*np.exp(-1j*self.k0)/(4*np.pi)
        E_theta = r_fac*(-L_phi + E_H_theta)
        E_phi = r_fac*(L_theta + E_H_phi)
        return (E_theta, E_phi)
    
    def calc_pt_E_H(self, theta_deg, phi_deg):
        theta = np.deg2rad(theta_deg)
        phi = np.deg2rad(phi_deg)
        rhat = np.array([np.sin(theta)*np.cos(phi),
                        np.sin(theta)*np.sin(phi),
                        np.cos(theta)], dtype=np.float64)
        theta_hat = np.array([np.cos(theta)*np.cos(phi),
                             np.cos(theta)*np.sin(phi),
                             -np.sin(theta)], dtype=np.float64)
        phi_hat = np.array([-np.sin(phi), np.cos(phi), 0.], dtype=np.float64)
        E_H_theta = self.calc_ff_func(rhat, theta_hat)
        E_H_phi = self.calc_ff_func(rhat, phi_hat)
        return E_H_theta, E_H_phi
    
    def calc_ff_func(self, rhat, ahat):
        self.testing_expression_gen.set_parms(rhat, ahat, self.k0)
        fit_expr_r, fit_expr_i = self.testing_expression_gen.get_expression()
        self.testing_interpolator.set_interpolant_expression(fit_expr_r, fit_expr_i)
        g_dofs = self.testing_interpolator.calculate_interpolation()
        self.functional.set_g_dofs(g_dofs)
        return self.functional.calc_functional()